diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-28 23:40:08 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-28 23:40:08 +0000 |
commit | a07893f87a159126bee7021e4175641539bc2a79 (patch) | |
tree | 000431e82565ab669f5d01ff230410b2abec9210 /base/mac | |
parent | 71c84e595de76d72dc517cd22a2b7d56294c784f (diff) | |
download | chromium_src-a07893f87a159126bee7021e4175641539bc2a79.zip chromium_src-a07893f87a159126bee7021e4175641539bc2a79.tar.gz chromium_src-a07893f87a159126bee7021e4175641539bc2a79.tar.bz2 |
Rewrite ScopedMachPort in terms of ScopedGeneric, making its usage more explicit and clear.
ScopedMachPort was only properly handling send rights, accidentally leaking
receive rights in some places. This adds an additional scoper for handling
receive rights.
BUG=none
R=mark@chromium.org
Review URL: https://codereview.chromium.org/294393007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273400 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/mac')
-rw-r--r-- | base/mac/scoped_mach_port.cc | 25 | ||||
-rw-r--r-- | base/mac/scoped_mach_port.h | 60 |
2 files changed, 52 insertions, 33 deletions
diff --git a/base/mac/scoped_mach_port.cc b/base/mac/scoped_mach_port.cc index 9e45a85..de94602 100644 --- a/base/mac/scoped_mach_port.cc +++ b/base/mac/scoped_mach_port.cc @@ -4,22 +4,27 @@ #include "base/mac/scoped_mach_port.h" +#include "base/mac/mach_logging.h" + namespace base { namespace mac { +namespace internal { -ScopedMachPort::ScopedMachPort(mach_port_t port) : port_(port) { -} - -ScopedMachPort::~ScopedMachPort() { - reset(); +// 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"; } -void ScopedMachPort::reset(mach_port_t port) { - if (port_ != MACH_PORT_NULL) { - mach_port_deallocate(mach_task_self(), port_); - } - port_ = port; +// 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"; } +} // namespace internal } // namespace mac } // namespace base diff --git a/base/mac/scoped_mach_port.h b/base/mac/scoped_mach_port.h index a98ca5e..36087c9 100644 --- a/base/mac/scoped_mach_port.h +++ b/base/mac/scoped_mach_port.h @@ -8,41 +8,55 @@ #include <mach/mach.h> #include "base/base_export.h" -#include "base/basictypes.h" -#include "base/compiler_specific.h" +#include "base/scoped_generic.h" namespace base { namespace mac { -// A class for managing the life of a Mach port, releasing via -// mach_port_deallocate either its send and/or receive rights. -class BASE_EXPORT ScopedMachPort { - public: - // Creates a scoper by taking ownership of the port. - explicit ScopedMachPort(mach_port_t port); +namespace internal { - ~ScopedMachPort(); +struct BASE_EXPORT SendRightTraits { + static mach_port_t InvalidValue() { + return MACH_PORT_NULL; + } - void reset(mach_port_t port = MACH_PORT_NULL); + static void Free(mach_port_t port); +}; - operator mach_port_t() const { - return port_; +struct BASE_EXPORT ReceiveRightTraits { + static mach_port_t InvalidValue() { + return MACH_PORT_NULL; } - mach_port_t get() const { - return port_; - } + static void Free(mach_port_t port); +}; - mach_port_t release() WARN_UNUSED_RESULT { - mach_port_t temp = port_; - port_ = MACH_PORT_NULL; - return temp; - } +} // namespace internal - private: - mach_port_t port_; +// A scoper for handling a Mach port that names a send right. Send rights are +// reference counted, and this takes ownership of the right on construction +// and then removes a reference to the right on destruction. If the reference +// is the last one on the right, the right is deallocated. +class BASE_EXPORT ScopedMachSendRight : + public base::ScopedGeneric<mach_port_t, internal::SendRightTraits> { + public: + explicit ScopedMachSendRight(mach_port_t port = traits_type::InvalidValue()) + : ScopedGeneric(port) {} + + operator mach_port_t() const { return get(); } +}; + +// A scoper for handling a Mach port's receive right. There is only one +// receive right per port. This takes ownership of the receive right on +// construction and then destroys the right on destruction, turning all +// outstanding send rights into dead names. +class BASE_EXPORT ScopedMachReceiveRight : + public base::ScopedGeneric<mach_port_t, internal::ReceiveRightTraits> { + public: + explicit ScopedMachReceiveRight( + mach_port_t port = traits_type::InvalidValue()) : ScopedGeneric(port) {} - DISALLOW_COPY_AND_ASSIGN(ScopedMachPort); + operator mach_port_t() const { return get(); } }; } // namespace mac |