]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/common/tri_mutex: add helpers for seastar::with_lock()
authorKefu Chai <kchai@redhat.com>
Wed, 16 Sep 2020 16:15:48 +0000 (00:15 +0800)
committerKefu Chai <kchai@redhat.com>
Sat, 19 Sep 2020 05:30:51 +0000 (13:30 +0800)
so we don't need to worry about unlocking the object context.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/crimson/common/tri_mutex.cc
src/crimson/common/tri_mutex.h

index 247f37436777bb8c7002398f5cebc32957bd04aa..7ec52522a70eb65b4120ef7958a51c10954eee7a 100644 (file)
@@ -3,6 +3,67 @@
 
 #include "tri_mutex.h"
 
+seastar::future<> read_lock::lock()
+{
+  return static_cast<tri_mutex*>(this)->lock_for_read();
+}
+
+void read_lock::unlock()
+{
+  static_cast<tri_mutex*>(this)->unlock_for_read();
+}
+
+seastar::future<> write_lock::lock()
+{
+  return static_cast<tri_mutex*>(this)->lock_for_write(false);
+}
+
+void write_lock::unlock()
+{
+  static_cast<tri_mutex*>(this)->unlock_for_write();
+}
+
+seastar::future<> excl_lock::lock()
+{
+  return static_cast<tri_mutex*>(this)->lock_for_excl();
+}
+
+void excl_lock::unlock()
+{
+  static_cast<tri_mutex*>(this)->unlock_for_excl();
+}
+
+seastar::future<> excl_lock_from_read::lock()
+{
+  static_cast<tri_mutex*>(this)->promote_from_read();
+  return seastar::make_ready_future<>();
+}
+
+void excl_lock_from_read::unlock()
+{
+  static_cast<tri_mutex*>(this)->demote_to_read();
+}
+
+seastar::future<> excl_lock_from_write::lock()
+{
+  static_cast<tri_mutex*>(this)->promote_from_write();
+  return seastar::make_ready_future<>();
+}
+
+void excl_lock_from_write::unlock()
+{
+  static_cast<tri_mutex*>(this)->demote_to_write();
+}
+
+seastar::future<> excl_lock_from_excl::lock()
+{
+  return seastar::make_ready_future<>();
+}
+
+void excl_lock_from_excl::unlock()
+{
+}
+
 seastar::future<> tri_mutex::lock_for_read()
 {
   if (try_lock_for_read()) {
@@ -30,6 +91,20 @@ void tri_mutex::unlock_for_read()
   }
 }
 
+void tri_mutex::promote_from_read()
+{
+  assert(readers == 1);
+  --readers;
+  exclusively_used = true;
+}
+
+void tri_mutex::demote_to_read()
+{
+  assert(exclusively_used);
+  exclusively_used = false;
+  ++readers;
+}
+
 seastar::future<> tri_mutex::lock_for_write(bool greedy)
 {
   if (try_lock_for_write(greedy)) {
@@ -58,6 +133,20 @@ void tri_mutex::unlock_for_write()
   }
 }
 
+void tri_mutex::promote_from_write()
+{
+  assert(writers == 1);
+  --writers;
+  exclusively_used = true;
+}
+
+void tri_mutex::demote_to_write()
+{
+  assert(exclusively_used);
+  exclusively_used = false;
+  ++writers;
+}
+
 // for exclusive users
 seastar::future<> tri_mutex::lock_for_excl()
 {
index 27553f4abad13a433f6a7aba54f87d83ceb2e686..3092c6f305cc97afdaa8a95907f4f5cd03a71c40 100644 (file)
@@ -6,6 +6,45 @@
 #include <seastar/core/future.hh>
 #include <seastar/core/circular_buffer.hh>
 
+class read_lock {
+public:
+  seastar::future<> lock();
+  void unlock();
+};
+
+class write_lock {
+public:
+  seastar::future<> lock();
+  void unlock();
+};
+
+class excl_lock {
+public:
+  seastar::future<> lock();
+  void unlock();
+};
+
+// promote from read to excl
+class excl_lock_from_read {
+public:
+  seastar::future<> lock();
+  void unlock();
+};
+
+// promote from write to excl
+class excl_lock_from_write {
+public:
+  seastar::future<> lock();
+  void unlock();
+};
+
+// promote from excl to excl
+class excl_lock_from_excl {
+public:
+  seastar::future<> lock();
+  void unlock();
+};
+
 /// shared/exclusive mutual exclusion
 ///
 /// this lock design uses reader and writer is entirely and completely
 /// - readers
 /// - writers
 /// - exclusive users
-class tri_mutex {
+class tri_mutex : private read_lock,
+                          write_lock,
+                          excl_lock,
+                          excl_lock_from_read,
+                          excl_lock_from_write,
+                          excl_lock_from_excl
+{
 public:
   tri_mutex() = default;
+
+  read_lock& for_read() {
+    return *this;
+  }
+  write_lock& for_write() {
+    return *this;
+  }
+  excl_lock& for_excl() {
+    return *this;
+  }
+  excl_lock_from_read& excl_from_read() {
+    return *this;
+  }
+  excl_lock_from_write& excl_from_write() {
+    return *this;
+  }
+  excl_lock_from_write& excl_from_excl() {
+    return *this;
+  }
+
   // for shared readers
   seastar::future<> lock_for_read();
   bool try_lock_for_read() noexcept;
   void unlock_for_read();
+  void promote_from_read();
+  void demote_to_read();
+
   // for shared writers
   seastar::future<> lock_for_write(bool greedy);
   bool try_lock_for_write(bool greedy) noexcept;
   void unlock_for_write();
+  void promote_from_write();
+  void demote_to_write();
+
   // for exclusive users
   seastar::future<> lock_for_excl();
   bool try_lock_for_excl() noexcept;
@@ -66,4 +137,10 @@ private:
     type_t type;
   };
   seastar::circular_buffer<waiter_t> waiters;
+  friend class read_lock;
+  friend class write_lock;
+  friend class excl_lock;
+  friend class excl_lock_from_read;
+  friend class excl_lock_from_write;
+  friend class excl_lock_from_excl;
 };