From: Kefu Chai Date: Wed, 16 Sep 2020 16:15:48 +0000 (+0800) Subject: crimson/common/tri_mutex: add helpers for seastar::with_lock() X-Git-Tag: v16.1.0~1019^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c90bbc0630eb50cd95009a57ef07918cb5276b94;p=ceph.git crimson/common/tri_mutex: add helpers for seastar::with_lock() so we don't need to worry about unlocking the object context. Signed-off-by: Kefu Chai --- diff --git a/src/crimson/common/tri_mutex.cc b/src/crimson/common/tri_mutex.cc index 247f37436777..7ec52522a70e 100644 --- a/src/crimson/common/tri_mutex.cc +++ b/src/crimson/common/tri_mutex.cc @@ -3,6 +3,67 @@ #include "tri_mutex.h" +seastar::future<> read_lock::lock() +{ + return static_cast(this)->lock_for_read(); +} + +void read_lock::unlock() +{ + static_cast(this)->unlock_for_read(); +} + +seastar::future<> write_lock::lock() +{ + return static_cast(this)->lock_for_write(false); +} + +void write_lock::unlock() +{ + static_cast(this)->unlock_for_write(); +} + +seastar::future<> excl_lock::lock() +{ + return static_cast(this)->lock_for_excl(); +} + +void excl_lock::unlock() +{ + static_cast(this)->unlock_for_excl(); +} + +seastar::future<> excl_lock_from_read::lock() +{ + static_cast(this)->promote_from_read(); + return seastar::make_ready_future<>(); +} + +void excl_lock_from_read::unlock() +{ + static_cast(this)->demote_to_read(); +} + +seastar::future<> excl_lock_from_write::lock() +{ + static_cast(this)->promote_from_write(); + return seastar::make_ready_future<>(); +} + +void excl_lock_from_write::unlock() +{ + static_cast(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() { diff --git a/src/crimson/common/tri_mutex.h b/src/crimson/common/tri_mutex.h index 27553f4abad1..3092c6f305cc 100644 --- a/src/crimson/common/tri_mutex.h +++ b/src/crimson/common/tri_mutex.h @@ -6,6 +6,45 @@ #include #include +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 @@ -19,17 +58,49 @@ /// - 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 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; };