]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/seastar/include/seastar/core/shared_mutex.hh
import quincy beta 17.1.0
[ceph.git] / ceph / src / seastar / include / seastar / core / shared_mutex.hh
index 553f47e7405a09a7be07257300bf54f0f5d5f64d..e1747028c45c7ef532f00fc4716e70b0cf39df68 100644 (file)
@@ -22,7 +22,7 @@
 #pragma once
 
 #include <seastar/core/future.hh>
-#include <seastar/core/circular_buffer.hh>
+#include <seastar/core/chunked_fifo.hh>
 
 namespace seastar {
 
@@ -54,7 +54,7 @@ class shared_mutex {
         promise<> pr;
         bool for_write;
     };
-    circular_buffer<waiter> _waiters;
+    chunked_fifo<waiter> _waiters;
 public:
     shared_mutex() = default;
     shared_mutex(shared_mutex&&) = default;
@@ -65,12 +65,16 @@ public:
     ///
     /// \return a future that becomes ready when no exclusive access
     ///         is granted to anyone.
-    future<> lock_shared() {
+    future<> lock_shared() noexcept {
         if (try_lock_shared()) {
             return make_ready_future<>();
         }
-        _waiters.emplace_back(promise<>(), false);
-        return _waiters.back().pr.get_future();
+        try {
+            _waiters.emplace_back(promise<>(), false);
+            return _waiters.back().pr.get_future();
+        } catch (...) {
+            return current_exception_as_future();
+        }
     }
     /// Try to lock the \c shared_mutex for shared access
     ///
@@ -83,7 +87,7 @@ public:
         return false;
     }
     /// Unlocks a \c shared_mutex after a previous call to \ref lock_shared().
-    void unlock_shared() {
+    void unlock_shared() noexcept {
         assert(_readers > 0);
         --_readers;
         wake();
@@ -92,12 +96,16 @@ public:
     ///
     /// \return a future that becomes ready when no access, shared or exclusive
     ///         is granted to anyone.
-    future<> lock() {
+    future<> lock() noexcept {
         if (try_lock()) {
             return make_ready_future<>();
         }
-        _waiters.emplace_back(promise<>(), true);
-        return _waiters.back().pr.get_future();
+        try {
+            _waiters.emplace_back(promise<>(), true);
+            return _waiters.back().pr.get_future();
+        } catch (...) {
+            return current_exception_as_future();
+        }
     }
     /// Try to lock the \c shared_mutex for exclusive access
     ///
@@ -110,13 +118,13 @@ public:
         return false;
     }
     /// Unlocks a \c shared_mutex after a previous call to \ref lock().
-    void unlock() {
+    void unlock() noexcept {
         assert(_writer);
         _writer = false;
         wake();
     }
 private:
-    void wake() {
+    void wake() noexcept {
         while (!_waiters.empty()) {
             auto& w = _waiters.front();
             // note: _writer == false in wake()
@@ -147,9 +155,16 @@ private:
 ///
 /// \relates shared_mutex
 template <typename Func>
-inline
-futurize_t<std::result_of_t<Func ()>>
-with_shared(shared_mutex& sm, Func&& func) {
+SEASTAR_CONCEPT(
+    requires (std::invocable<Func> && std::is_nothrow_move_constructible_v<Func>)
+    inline
+    futurize_t<std::invoke_result_t<Func>>
+)
+SEASTAR_NO_CONCEPT(
+    inline
+    std::enable_if_t<std::is_nothrow_move_constructible_v<Func>, futurize_t<std::result_of_t<Func ()>>>
+)
+with_shared(shared_mutex& sm, Func&& func) noexcept {
     return sm.lock_shared().then([&sm, func = std::forward<Func>(func)] () mutable {
         return futurize_invoke(func).finally([&sm] {
             sm.unlock_shared();
@@ -157,6 +172,31 @@ with_shared(shared_mutex& sm, Func&& func) {
     });
 }
 
+template <typename Func>
+SEASTAR_CONCEPT(
+    requires (std::invocable<Func> && !std::is_nothrow_move_constructible_v<Func>)
+    inline
+    futurize_t<std::invoke_result_t<Func>>
+)
+SEASTAR_NO_CONCEPT(
+    inline
+    std::enable_if_t<!std::is_nothrow_move_constructible_v<Func>, futurize_t<std::result_of_t<Func ()>>>
+)
+with_shared(shared_mutex& sm, Func&& func) noexcept {
+    // FIXME: use a coroutine when c++17 support is dropped
+    try {
+        return do_with(std::forward<Func>(func), [&sm] (Func& func) {
+            return sm.lock_shared().then([&func] {
+                return func();
+            }).finally([&sm] {
+                sm.unlock_shared();
+            });
+        });
+    } catch (...) {
+        return current_exception_as_future();
+    }
+}
+
 /// Executes a function while holding exclusive access to a resource.
 ///
 /// Executes a function while holding exclusive access to a resource.  When
@@ -168,9 +208,16 @@ with_shared(shared_mutex& sm, Func&& func) {
 ///
 /// \relates shared_mutex
 template <typename Func>
-inline
-futurize_t<std::result_of_t<Func ()>>
-with_lock(shared_mutex& sm, Func&& func) {
+SEASTAR_CONCEPT(
+    requires (std::invocable<Func> && std::is_nothrow_move_constructible_v<Func>)
+    inline
+    futurize_t<std::invoke_result_t<Func>>
+)
+SEASTAR_NO_CONCEPT(
+    inline
+    std::enable_if_t<std::is_nothrow_move_constructible_v<Func>, futurize_t<std::result_of_t<Func ()>>>
+)
+with_lock(shared_mutex& sm, Func&& func) noexcept {
     return sm.lock().then([&sm, func = std::forward<Func>(func)] () mutable {
         return futurize_invoke(func).finally([&sm] {
             sm.unlock();
@@ -178,6 +225,32 @@ with_lock(shared_mutex& sm, Func&& func) {
     });
 }
 
+
+template <typename Func>
+SEASTAR_CONCEPT(
+    requires (std::invocable<Func> && !std::is_nothrow_move_constructible_v<Func>)
+    inline
+    futurize_t<std::invoke_result_t<Func>>
+)
+SEASTAR_NO_CONCEPT(
+    inline
+    std::enable_if_t<!std::is_nothrow_move_constructible_v<Func>, futurize_t<std::result_of_t<Func ()>>>
+)
+with_lock(shared_mutex& sm, Func&& func) noexcept {
+    // FIXME: use a coroutine when c++17 support is dropped
+    try {
+        return do_with(std::forward<Func>(func), [&sm] (Func& func) {
+            return sm.lock().then([&func] {
+                return func();
+            }).finally([&sm] {
+                sm.unlock();
+            });
+        });
+    } catch (...) {
+        return current_exception_as_future();
+    }
+}
+
 /// @}
 
 }