You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2013/12/02 17:56:56 UTC

[02/14] git commit: Refactored Owned and added a function Owned::share().

Refactored Owned and added a function Owned::share().

From: Jie Yu <yu...@gmail.com>
Review: https://reviews.apache.org/r/15731


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/845ff1be
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/845ff1be
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/845ff1be

Branch: refs/heads/master
Commit: 845ff1be9d0f6a67726659c143a2457799bbb3de
Parents: 6b13a6e
Author: Benjamin Hindman <be...@gmail.com>
Authored: Sun Dec 1 15:48:48 2013 -0800
Committer: Benjamin Hindman <be...@gmail.com>
Committed: Sun Dec 1 15:48:48 2013 -0800

----------------------------------------------------------------------
 3rdparty/libprocess/Makefile.am               |   2 +
 3rdparty/libprocess/include/process/owned.hpp | 166 +++++++++++++++++++++
 3rdparty/libprocess/src/tests/owned_tests.cpp |  80 ++++++++++
 3 files changed, 248 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/845ff1be/3rdparty/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/Makefile.am b/3rdparty/libprocess/Makefile.am
index d348780..47e6d02 100644
--- a/3rdparty/libprocess/Makefile.am
+++ b/3rdparty/libprocess/Makefile.am
@@ -82,6 +82,7 @@ libprocess_la_SOURCES +=					\
   $(top_srcdir)/include/process/message.hpp			\
   $(top_srcdir)/include/process/mime.hpp			\
   $(top_srcdir)/include/process/once.hpp			\
+  $(top_srcdir)/include/process/owned.hpp			\
   $(top_srcdir)/include/process/pid.hpp				\
   $(top_srcdir)/include/process/process.hpp			\
   $(top_srcdir)/include/process/profiler.hpp			\
@@ -103,6 +104,7 @@ tests_SOURCES =							\
   src/tests/http_tests.cpp					\
   src/tests/io_tests.cpp					\
   src/tests/main.cpp						\
+  src/tests/owned_tests.cpp					\
   src/tests/process_tests.cpp					\
   src/tests/shared_tests.cpp					\
   src/tests/statistics_tests.cpp				\

http://git-wip-us.apache.org/repos/asf/mesos/blob/845ff1be/3rdparty/libprocess/include/process/owned.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/owned.hpp b/3rdparty/libprocess/include/process/owned.hpp
new file mode 100644
index 0000000..4a03ea4
--- /dev/null
+++ b/3rdparty/libprocess/include/process/owned.hpp
@@ -0,0 +1,166 @@
+#ifndef __PROCESS_OWNED_HPP__
+#define __PROCESS_OWNED_HPP__
+
+#include <glog/logging.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace process {
+
+// Forward declaration.
+template <typename T>
+class Shared;
+
+
+// Represents a uniquely owned pointer.
+//
+// TODO(bmahler): For now, Owned only provides shared_ptr semantics.
+// When we make the switch to C++11, we will change to provide
+// unique_ptr semantics. Consequently, each usage of Owned that
+// invoked a copy will have to be adjusted to use move semantics.
+template <typename T>
+class Owned
+{
+public:
+  Owned();
+  explicit Owned(T* t);
+
+  bool operator == (const Owned<T>& that) const;
+  bool operator < (const Owned<T>& that) const;
+
+  T& operator * () const;
+  T* operator -> () const;
+  T* get() const;
+
+  void reset();
+  void reset(T* t);
+  void swap(Owned<T>& that);
+
+  // Converts from an owned pointer to a shared pointer. This owned
+  // pointer will be reset after this function is invoked.
+  Shared<T> share();
+
+private:
+  struct Data
+  {
+    Data(T* t);
+    ~Data();
+
+    T* volatile t; // The pointer 't' is volatile.
+  };
+
+  boost::shared_ptr<Data> data;
+};
+
+
+template <typename T>
+Owned<T>::Owned() {}
+
+
+template <typename T>
+Owned<T>::Owned(T* t)
+{
+  if (t != NULL) {
+    data.reset(new Data(t));
+  }
+}
+
+
+template <typename T>
+bool Owned<T>::operator == (const Owned<T>& that) const
+{
+  return data == that.data;
+}
+
+
+template <typename T>
+bool Owned<T>::operator < (const Owned<T>& that) const
+{
+  return data < that.data;
+}
+
+
+template <typename T>
+T& Owned<T>::operator * () const
+{
+  return *CHECK_NOTNULL(get());
+}
+
+
+template <typename T>
+T* Owned<T>::operator -> () const
+{
+  return CHECK_NOTNULL(get());
+}
+
+
+template <typename T>
+T* Owned<T>::get() const
+{
+  if (data.get() == NULL) {
+    return NULL;
+  } else {
+    CHECK(data->t != NULL) << "This owned pointer has already been shared";
+
+    return data->t;
+  }
+}
+
+
+template <typename T>
+void Owned<T>::reset()
+{
+  data.reset();
+}
+
+
+template <typename T>
+void Owned<T>::reset(T* t)
+{
+  if (t == NULL) {
+    data.reset();
+  } else {
+    data.reset(new Data(t));
+  }
+}
+
+
+template <typename T>
+void Owned<T>::swap(Owned<T>& that)
+{
+  data.swap(that.data);
+}
+
+
+template <typename T>
+Shared<T> Owned<T>::share()
+{
+  if (data.get() == NULL) {
+    return Shared<T>(NULL);
+  }
+
+  // Atomically set the pointer 'data->t' to NULL.
+  T* t = __sync_fetch_and_and(&data->t, NULL);
+  CHECK(t != NULL) << "The ownership of this pointer has already been shared";
+
+  data.reset();
+  return Shared<T>(t);
+}
+
+
+template <typename T>
+Owned<T>::Data::Data(T* _t)
+  : t(CHECK_NOTNULL(_t)) {}
+
+
+template <typename T>
+Owned<T>::Data::~Data()
+{
+  if (t != NULL) {
+    delete t;
+  }
+}
+
+} // namespace process {
+
+#endif // __PROCESS_OWNED_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/845ff1be/3rdparty/libprocess/src/tests/owned_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/owned_tests.cpp b/3rdparty/libprocess/src/tests/owned_tests.cpp
new file mode 100644
index 0000000..234469b
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/owned_tests.cpp
@@ -0,0 +1,80 @@
+#include <gmock/gmock.h>
+
+#include <process/gtest.hpp>
+#include <process/owned.hpp>
+#include <process/shared.hpp>
+
+using namespace process;
+
+class Foo
+{
+public:
+  int get() const { return value; }
+  void set(int _value) { value = _value; }
+
+private:
+  int value;
+};
+
+
+TEST(Owned, Access)
+{
+  Foo* foo = new Foo();
+  foo->set(42);
+
+  Owned<Foo> owned(foo);
+
+  EXPECT_EQ(42, owned->get());
+  EXPECT_EQ(42, (*owned).get());
+  EXPECT_EQ(42, owned.get()->get());
+
+  owned->set(10);
+
+  EXPECT_EQ(10, owned->get());
+  EXPECT_EQ(10, (*owned).get());
+  EXPECT_EQ(10, owned.get()->get());
+}
+
+
+TEST(Owned, Null)
+{
+  Owned<Foo> owned;
+  Owned<Foo> owned2(NULL);
+
+  EXPECT_TRUE(owned.get() == NULL);
+  EXPECT_TRUE(owned2.get() == NULL);
+}
+
+
+TEST(Owned, Share)
+{
+  Foo* foo = new Foo();
+  foo->set(42);
+
+  Owned<Foo> owned(foo);
+
+  EXPECT_EQ(42, owned->get());
+  EXPECT_EQ(42, (*owned).get());
+  EXPECT_EQ(42, owned.get()->get());
+
+  Shared<Foo> shared = owned.share();
+
+  EXPECT_TRUE(owned.get() == NULL);
+  EXPECT_TRUE(shared.unique());
+
+  EXPECT_EQ(42, shared->get());
+  EXPECT_EQ(42, (*shared).get());
+  EXPECT_EQ(42, shared.get()->get());
+
+  {
+    Shared<Foo> shared2(shared);
+
+    EXPECT_EQ(42, shared2->get());
+    EXPECT_EQ(42, (*shared2).get());
+    EXPECT_EQ(42, shared2.get()->get());
+    EXPECT_FALSE(shared.unique());
+    EXPECT_FALSE(shared2.unique());
+  }
+
+  EXPECT_TRUE(shared.unique());
+}