1 // Copyright 2012 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 #include "base/apple/scoped_mach_port.h"
6
7 #include "base/apple/mach_logging.h"
8
9 namespace base::apple {
10 namespace internal {
11
12 // static
Free(mach_port_t port)13 void SendRightTraits::Free(mach_port_t port) {
14 kern_return_t kr = mach_port_deallocate(mach_task_self(), port);
15 MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr)
16 << "ScopedMachSendRight mach_port_deallocate";
17 }
18
19 // static
Free(mach_port_t port)20 void ReceiveRightTraits::Free(mach_port_t port) {
21 kern_return_t kr =
22 mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1);
23 MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr)
24 << "ScopedMachReceiveRight mach_port_mod_refs";
25 }
26
27 // static
Free(mach_port_t port)28 void PortSetTraits::Free(mach_port_t port) {
29 kern_return_t kr =
30 mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_PORT_SET, -1);
31 MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr)
32 << "ScopedMachPortSet mach_port_mod_refs";
33 }
34
35 } // namespace internal
36
CreateMachPort(ScopedMachReceiveRight * receive,ScopedMachSendRight * send,std::optional<mach_port_msgcount_t> queue_limit)37 bool CreateMachPort(ScopedMachReceiveRight* receive,
38 ScopedMachSendRight* send,
39 std::optional<mach_port_msgcount_t> queue_limit) {
40 mach_port_options_t options{};
41 options.flags = (send != nullptr ? MPO_INSERT_SEND_RIGHT : 0);
42
43 if (queue_limit.has_value()) {
44 options.flags |= MPO_QLIMIT;
45 options.mpl.mpl_qlimit = *queue_limit;
46 }
47
48 kern_return_t kr =
49 mach_port_construct(mach_task_self(), &options, 0,
50 ScopedMachReceiveRight::Receiver(*receive).get());
51 if (kr != KERN_SUCCESS) {
52 MACH_LOG(ERROR, kr) << "mach_port_construct";
53 return false;
54 }
55
56 // Multiple rights are coalesced to the same name in a task, so assign the
57 // send rights to the same name.
58 if (send) {
59 send->reset(receive->get());
60 }
61
62 return true;
63 }
64
RetainMachSendRight(mach_port_t port)65 ScopedMachSendRight RetainMachSendRight(mach_port_t port) {
66 kern_return_t kr =
67 mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, 1);
68 if (kr == KERN_SUCCESS) {
69 return ScopedMachSendRight(port);
70 }
71 MACH_DLOG(ERROR, kr) << "mach_port_mod_refs +1";
72 return {};
73 }
74
75 } // namespace base::apple
76