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