mach_port_mac.h 3.7 KB

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