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