summaryrefslogtreecommitdiffstats
path: root/base/mac
diff options
context:
space:
mode:
authorrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-28 23:40:08 +0000
committerrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-28 23:40:08 +0000
commita07893f87a159126bee7021e4175641539bc2a79 (patch)
tree000431e82565ab669f5d01ff230410b2abec9210 /base/mac
parent71c84e595de76d72dc517cd22a2b7d56294c784f (diff)
downloadchromium_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.cc25
-rw-r--r--base/mac/scoped_mach_port.h60
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