erikchen | 1c1e665 | 2015-10-01 18:51:32 | [diff] [blame] | 1 | // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef IPC_MACH_PORT_MAC_H_ |
| 6 | #define IPC_MACH_PORT_MAC_H_ |
| 7 | |
| 8 | #include <mach/mach.h> |
| 9 | |
erikchen | 3722a32 | 2015-10-07 20:51:55 | [diff] [blame] | 10 | #include "base/macros.h" |
erikchen | 1c1e665 | 2015-10-01 18:51:32 | [diff] [blame] | 11 | #include "ipc/ipc_export.h" |
| 12 | #include "ipc/ipc_message_macros.h" |
| 13 | |
| 14 | namespace IPC { |
| 15 | |
erikchen | 3722a32 | 2015-10-07 20:51:55 | [diff] [blame] | 16 | // MachPortMac is a wrapper around an OSX Mach port that can be transported |
| 17 | // across Chrome IPC channels that support attachment brokering. The send right |
| 18 | // to the Mach port will be duplicated into the destination process by the |
| 19 | // attachment broker. If needed, attachment brokering can be trivially extended |
| 20 | // to support duplication of other types of rights. |
erikchen | 1c1e665 | 2015-10-01 18:51:32 | [diff] [blame] | 21 | class IPC_EXPORT MachPortMac { |
| 22 | public: |
| 23 | MachPortMac() : mach_port_(MACH_PORT_NULL) {} |
erikchen | 3722a32 | 2015-10-07 20:51:55 | [diff] [blame] | 24 | |
erikchen | af8299d | 2015-10-09 19:12:06 | [diff] [blame] | 25 | explicit MachPortMac(mach_port_t mach_port) : mach_port_(mach_port) {} |
erikchen | 1c1e665 | 2015-10-01 18:51:32 | [diff] [blame] | 26 | |
| 27 | mach_port_t get_mach_port() const { return mach_port_; } |
erikchen | 3722a32 | 2015-10-07 20:51:55 | [diff] [blame] | 28 | |
| 29 | // This method should only be used by ipc/ translation code. |
erikchen | 1c1e665 | 2015-10-01 18:51:32 | [diff] [blame] | 30 | void set_mach_port(mach_port_t mach_port) { mach_port_ = mach_port; } |
| 31 | |
| 32 | private: |
erikchen | 3722a32 | 2015-10-07 20:51:55 | [diff] [blame] | 33 | // The ownership semantics of |mach_port_| cannot be easily expressed with a |
| 34 | // C++ scoped object. This is partly due to the mechanism by which Mach ports |
| 35 | // are brokered, and partly due to the architecture of Chrome IPC. |
| 36 | // |
| 37 | // The broker for Mach ports may live in a different process than the sender |
| 38 | // of the original Chrome IPC. In this case, it is signalled asynchronously, |
| 39 | // and ownership of the Mach port passes from the sender process into the |
| 40 | // broker process. |
| 41 | // |
| 42 | // Chrome IPC is written with the assumption that translation is a stateless |
| 43 | // process. There is no good mechanism to convey the semantics of ownership |
| 44 | // transfer from the Chrome IPC stack into the client code that receives the |
| 45 | // translated message. As a result, Chrome IPC code assumes that every message |
| 46 | // has a handler, and that the handler will take ownership of the Mach port. |
| 47 | // Note that the same holds true for POSIX fds and Windows HANDLEs. |
| 48 | // |
| 49 | // When used by client code in the sender process, this class is just a |
| 50 | // wrapper. The client code calls Send(new Message(MachPortMac(mach_port))) |
| 51 | // and continues on its merry way. Behind the scenes, a MachPortAttachmentMac |
| 52 | // takes ownership of the Mach port. When the attachment broker sends the name |
| 53 | // of the Mach port to the broker process, it also releases |
| 54 | // MachPortAttachmentMac's reference to the Mach port, as ownership has |
| 55 | // effectively been transferred to the broker process. |
| 56 | // |
| 57 | // The broker process receives the name, duplicates the Mach port into the |
| 58 | // destination process, and then decrements the ref count in the original |
| 59 | // process. |
| 60 | // |
| 61 | // In the destination process, the attachment broker is responsible for |
| 62 | // coupling the Mach port (inserted by the broker process) with Chrome IPC in |
| 63 | // the form of a MachPortAttachmentMac. Due to the Chrome IPC translation |
| 64 | // semantics discussed above, this MachPortAttachmentMac does not take |
| 65 | // ownership of the Mach port, and assumes that the client code which receives |
| 66 | // the callback will take ownership of the Mach port. |
erikchen | 1c1e665 | 2015-10-01 18:51:32 | [diff] [blame] | 67 | mach_port_t mach_port_; |
erikchen | 3722a32 | 2015-10-07 20:51:55 | [diff] [blame] | 68 | DISALLOW_COPY_AND_ASSIGN(MachPortMac); |
erikchen | 1c1e665 | 2015-10-01 18:51:32 | [diff] [blame] | 69 | }; |
| 70 | |
| 71 | template <> |
| 72 | struct IPC_EXPORT ParamTraits<MachPortMac> { |
| 73 | typedef MachPortMac param_type; |
rockot | 502c94f | 2016-02-03 20:20:16 | [diff] [blame^] | 74 | static void Write(base::Pickle* m, const param_type& p); |
| 75 | static bool Read(const base::Pickle* m, |
| 76 | base::PickleIterator* iter, |
| 77 | param_type* p); |
erikchen | 1c1e665 | 2015-10-01 18:51:32 | [diff] [blame] | 78 | static void Log(const param_type& p, std::string* l); |
| 79 | }; |
| 80 | |
| 81 | } // namespace IPC |
| 82 | |
| 83 | #endif // IPC_MACH_PORT_MAC_H_ |