blob: 6dea806ebe02f68c6d452a66e61b5a71052e8393 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/mac/scoped_mach_port.h"
#include "base/mac/mach_logging.h"
namespace base::mac {
namespace internal {
// static
void SendRightTraits::Free(mach_port_t port) {
kern_return_t kr = mach_port_deallocate(mach_task_self(), port);
MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr)
<< "ScopedMachSendRight mach_port_deallocate";
}
// static
void ReceiveRightTraits::Free(mach_port_t port) {
kern_return_t kr =
mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1);
MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr)
<< "ScopedMachReceiveRight mach_port_mod_refs";
}
// static
void PortSetTraits::Free(mach_port_t port) {
kern_return_t kr =
mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_PORT_SET, -1);
MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr)
<< "ScopedMachPortSet mach_port_mod_refs";
}
} // namespace internal
bool CreateMachPort(ScopedMachReceiveRight* receive,
ScopedMachSendRight* send,
absl::optional<mach_port_msgcount_t> queue_limit) {
mach_port_options_t options{};
options.flags = (send != nullptr ? MPO_INSERT_SEND_RIGHT : 0);
if (queue_limit.has_value()) {
options.flags |= MPO_QLIMIT;
options.mpl.mpl_qlimit = *queue_limit;
}
kern_return_t kr =
mach_port_construct(mach_task_self(), &options, 0,
ScopedMachReceiveRight::Receiver(*receive).get());
if (kr != KERN_SUCCESS) {
MACH_LOG(ERROR, kr) << "mach_port_construct";
return false;
}
// Multiple rights are coalesced to the same name in a task, so assign the
// send rights to the same name.
if (send) {
send->reset(receive->get());
}
return true;
}
ScopedMachSendRight RetainMachSendRight(mach_port_t port) {
kern_return_t kr =
mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, 1);
if (kr == KERN_SUCCESS)
return ScopedMachSendRight(port);
MACH_DLOG(ERROR, kr) << "mach_port_mod_refs +1";
return {};
}
} // namespace base::mac