summaryrefslogtreecommitdiffstats
path: root/ipc/mach_port_mac.h
blob: b95a37b47d036786f592aed06fa4177d98e48b41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IPC_MACH_PORT_MAC_H_
#define IPC_MACH_PORT_MAC_H_

#include <mach/mach.h>

#include "base/macros.h"
#include "ipc/ipc_export.h"
#include "ipc/ipc_message_macros.h"

namespace IPC {

// MachPortMac is a wrapper around an OSX Mach port that can be transported
// across Chrome IPC channels that support attachment brokering. The send right
// to the Mach port will be duplicated into the destination process by the
// attachment broker. If needed, attachment brokering can be trivially extended
// to support duplication of other types of rights.
class IPC_EXPORT MachPortMac {
 public:
  MachPortMac() : mach_port_(MACH_PORT_NULL) {}

  explicit MachPortMac(mach_port_t mach_port) : mach_port_(mach_port) {}

  mach_port_t get_mach_port() const { return mach_port_; }

  // This method should only be used by ipc/ translation code.
  void set_mach_port(mach_port_t mach_port) { mach_port_ = mach_port; }

 private:
  // The ownership semantics of |mach_port_| cannot be easily expressed with a
  // C++ scoped object. This is partly due to the mechanism by which Mach ports
  // are brokered, and partly due to the architecture of Chrome IPC.
  //
  // The broker for Mach ports may live in a different process than the sender
  // of the original Chrome IPC. In this case, it is signalled asynchronously,
  // and ownership of the Mach port passes from the sender process into the
  // broker process.
  //
  // Chrome IPC is written with the assumption that translation is a stateless
  // process. There is no good mechanism to convey the semantics of ownership
  // transfer from the Chrome IPC stack into the client code that receives the
  // translated message. As a result, Chrome IPC code assumes that every message
  // has a handler, and that the handler will take ownership of the Mach port.
  // Note that the same holds true for POSIX fds and Windows HANDLEs.
  //
  // When used by client code in the sender process, this class is just a
  // wrapper. The client code calls Send(new Message(MachPortMac(mach_port)))
  // and continues on its merry way. Behind the scenes, a MachPortAttachmentMac
  // takes ownership of the Mach port. When the attachment broker sends the name
  // of the Mach port to the broker process, it also releases
  // MachPortAttachmentMac's reference to the Mach port, as ownership has
  // effectively been transferred to the broker process.
  //
  // The broker process receives the name, duplicates the Mach port into the
  // destination process, and then decrements the ref count in the original
  // process.
  //
  // In the destination process, the attachment broker is responsible for
  // coupling the Mach port (inserted by the broker process) with Chrome IPC in
  // the form of a MachPortAttachmentMac. Due to the Chrome IPC translation
  // semantics discussed above, this MachPortAttachmentMac does not take
  // ownership of the Mach port, and assumes that the client code which receives
  // the callback will take ownership of the Mach port.
  mach_port_t mach_port_;
  DISALLOW_COPY_AND_ASSIGN(MachPortMac);
};

template <>
struct IPC_EXPORT ParamTraits<MachPortMac> {
  typedef MachPortMac param_type;
  static void Write(base::Pickle* m, const param_type& p);
  static bool Read(const base::Pickle* m,
                   base::PickleIterator* iter,
                   param_type* p);
  static void Log(const param_type& p, std::string* l);
};

}  // namespace IPC

#endif  // IPC_MACH_PORT_MAC_H_