Removed Common

Change-Id: I01ea8f07220375c2ad9bc0092281d4f27c642303
diff --git a/aos/stl_mutex/BUILD b/aos/stl_mutex/BUILD
new file mode 100644
index 0000000..a9b7957
--- /dev/null
+++ b/aos/stl_mutex/BUILD
@@ -0,0 +1,26 @@
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+    name = "stl_mutex",
+    hdrs = [
+        "stl_mutex.h",
+    ],
+    deps = [
+        "//aos/logging",
+        "//aos/linux_code/ipc_lib:aos_sync",
+    ],
+)
+
+cc_test(
+    name = "stl_mutex_test",
+    srcs = [
+        "stl_mutex_test.cc",
+    ],
+    deps = [
+        "//aos:die",
+        ":stl_mutex",
+        "//aos/util:thread",
+        "//aos/testing:googletest",
+        "//aos/testing:test_logging",
+    ],
+)
diff --git a/aos/stl_mutex/stl_mutex.h b/aos/stl_mutex/stl_mutex.h
new file mode 100644
index 0000000..a5ac807
--- /dev/null
+++ b/aos/stl_mutex/stl_mutex.h
@@ -0,0 +1,144 @@
+#ifndef AOS_STL_MUTEX_H_
+#define AOS_STL_MUTEX_H_
+
+#include <mutex>
+
+#include "aos/linux_code/ipc_lib/aos_sync.h"
+#include "aos/logging/logging.h"
+#include "aos/type_traits/type_traits.h"
+#include "aos/macros.h"
+
+namespace aos {
+
+// A mutex with the same API and semantics as ::std::mutex, with the addition of
+// methods for checking if the previous owner died and a constexpr default
+// constructor.
+// Definitely safe to put in SHM.
+// This uses the pthread_mutex semantics for owner-died: once somebody dies with
+// the lock held, anybody else who takes it will see true for owner_died() until
+// one of them calls consistent(). It is an error to call unlock() when
+// owner_died() returns true.
+class stl_mutex {
+ public:
+  constexpr stl_mutex() : native_handle_() {}
+
+  void lock() {
+    const int ret = mutex_grab(&native_handle_);
+    switch (ret) {
+      case 0:
+        break;
+      case 1:
+        owner_died_ = true;
+        break;
+      default:
+        LOG(FATAL, "mutex_grab(%p) failed with %d\n", &native_handle_, ret);
+    }
+  }
+
+  bool try_lock() {
+    const int ret = mutex_trylock(&native_handle_);
+    switch (ret) {
+      case 0:
+        return true;
+      case 1:
+        owner_died_ = true;
+        return true;
+      case 4:
+        return false;
+      default:
+        LOG(FATAL, "mutex_trylock(%p) failed with %d\n", &native_handle_, ret);
+    }
+  }
+
+  void unlock() {
+    CHECK(!owner_died_);
+    mutex_unlock(&native_handle_);
+  }
+
+  typedef aos_mutex *native_handle_type;
+  native_handle_type native_handle() { return &native_handle_; }
+
+  bool owner_died() const { return owner_died_; }
+  void consistent() { owner_died_ = false; }
+
+ private:
+  aos_mutex native_handle_;
+
+  bool owner_died_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(stl_mutex);
+};
+
+// A mutex with the same API and semantics as ::std::recursive_mutex, with the
+// addition of methods for checking if the previous owner died and a constexpr
+// default constructor.
+// Definitely safe to put in SHM.
+// This uses the pthread_mutex semantics for owner-died: once somebody dies with
+// the lock held, anybody else who takes it will see true for owner_died() until
+// one of them calls consistent(). It is an error to call unlock() or lock()
+// again when owner_died() returns true.
+class stl_recursive_mutex {
+ public:
+  constexpr stl_recursive_mutex() {}
+
+  void lock() {
+    if (mutex_islocked(mutex_.native_handle())) {
+      CHECK(!owner_died());
+      ++recursive_locks_;
+    } else {
+      mutex_.lock();
+      if (mutex_.owner_died()) {
+        recursive_locks_ = 0;
+      } else {
+        CHECK_EQ(0, recursive_locks_);
+      }
+    }
+  }
+  bool try_lock() {
+    if (mutex_islocked(mutex_.native_handle())) {
+      CHECK(!owner_died());
+      ++recursive_locks_;
+      return true;
+    } else {
+      if (mutex_.try_lock()) {
+        if (mutex_.owner_died()) {
+          recursive_locks_ = 0;
+        } else {
+          CHECK_EQ(0, recursive_locks_);
+        }
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+  void unlock() {
+    if (recursive_locks_ == 0) {
+      mutex_.unlock();
+    } else {
+      --recursive_locks_;
+    }
+  }
+
+  typedef stl_mutex::native_handle_type native_handle_type;
+  native_handle_type native_handle() { return mutex_.native_handle(); }
+
+  bool owner_died() const { return mutex_.owner_died(); }
+  void consistent() { mutex_.consistent(); }
+
+ private:
+  stl_mutex mutex_;
+  int recursive_locks_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(stl_recursive_mutex);
+};
+
+// Convenient typedefs for various types of locking objects.
+typedef ::std::lock_guard<stl_mutex> mutex_lock_guard;
+typedef ::std::lock_guard<stl_recursive_mutex> recursive_lock_guard;
+typedef ::std::unique_lock<stl_mutex> mutex_unique_lock;
+typedef ::std::unique_lock<stl_recursive_mutex> recursive_unique_lock;
+
+}  // namespace aos
+
+#endif  // AOS_STL_MUTEX_H_
diff --git a/aos/stl_mutex/stl_mutex_test.cc b/aos/stl_mutex/stl_mutex_test.cc
new file mode 100644
index 0000000..36d7067
--- /dev/null
+++ b/aos/stl_mutex/stl_mutex_test.cc
@@ -0,0 +1,74 @@
+#include "aos/stl_mutex/stl_mutex.h"
+
+#include "gtest/gtest.h"
+
+#include "aos/testing/test_logging.h"
+#include "aos/util/thread.h"
+#include "aos/die.h"
+
+namespace aos {
+namespace testing {
+
+class StlMutexDeathTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    ::aos::testing::EnableTestLogging();
+    SetDieTestMode(true);
+  }
+};
+
+typedef StlMutexDeathTest StlRecursiveMutexDeathTest;
+
+// Tests that locking/unlocking without any blocking works.
+TEST(StlMutexTest, Basic) {
+  stl_mutex mutex;
+
+  mutex.lock();
+  mutex.unlock();
+
+  ASSERT_TRUE(mutex.try_lock());
+  ASSERT_FALSE(mutex.try_lock());
+  mutex.unlock();
+
+  mutex.lock();
+  ASSERT_FALSE(mutex.try_lock());
+  mutex.unlock();
+}
+
+// Tests that unlocking an unlocked mutex fails.
+TEST_F(StlMutexDeathTest, MultipleUnlock) {
+  stl_mutex mutex;
+  mutex.lock();
+  mutex.unlock();
+  EXPECT_DEATH(mutex.unlock(), ".*multiple unlock.*");
+}
+
+// Tests that locking/unlocking (including recursively) without any blocking
+// works.
+TEST(StlRecursiveMutexTest, Basic) {
+  stl_recursive_mutex mutex;
+
+  mutex.lock();
+  mutex.unlock();
+
+  ASSERT_TRUE(mutex.try_lock());
+  ASSERT_TRUE(mutex.try_lock());
+  mutex.unlock();
+  mutex.unlock();
+
+  mutex.lock();
+  ASSERT_TRUE(mutex.try_lock());
+  mutex.unlock();
+	mutex.unlock();
+}
+
+// Tests that unlocking an unlocked recursive mutex fails.
+TEST_F(StlRecursiveMutexDeathTest, MultipleUnlock) {
+  stl_recursive_mutex mutex;
+  mutex.lock();
+  mutex.unlock();
+  EXPECT_DEATH(mutex.unlock(), ".*multiple unlock.*");
+}
+
+}  // namespace testing
+}  // namespace aos