xref: /aosp_15_r20/external/cronet/base/apple/scoped_mach_port.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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