25#include <seastar/core/coroutine.hh>
26#include <seastar/core/future.hh>
27#include <seastar/core/chunked_fifo.hh>
28#include <seastar/util/modules.hh>
32#include <shared_mutex>
37SEASTAR_MODULE_EXPORT_BEGIN
60 unsigned _readers = 0;
63 waiter(
promise<>&& pr,
bool for_write) : pr(std::move(pr)), for_write(for_write) {}
80 return make_ready_future<>();
83 _waiters.emplace_back(
promise<>(),
false);
84 return _waiters.back().pr.get_future();
93 if (!_writer && _waiters.empty()) {
101 assert(_readers > 0);
111 return make_ready_future<>();
114 _waiters.emplace_back(
promise<>(),
true);
115 return _waiters.back().pr.get_future();
124 if (!_readers && !_writer) {
137 void wake() noexcept {
138 while (!_waiters.empty()) {
139 auto& w = _waiters.front();
145 _waiters.pop_front();
151 _waiters.pop_front();
167template <std::invocable Func>
168 requires std::is_nothrow_move_constructible_v<Func>
170 futurize_t<std::invoke_result_t<Func>>
172 return sm.lock_shared().then([&sm, func = std::forward<Func>(func)] ()
mutable {
173 return futurize_invoke(func).finally([&sm] {
179template <std::invocable Func>
180 requires (!std::is_nothrow_move_constructible_v<Func>)
182 futurize_t<std::invoke_result_t<Func>>
186 return do_with(std::forward<Func>(func), [&sm] (Func& func) {
208template <std::invocable Func>
209 requires std::is_nothrow_move_constructible_v<Func>
211 futurize_t<std::invoke_result_t<Func>>
213 return sm.
lock().
then([&sm, func = std::forward<Func>(func)] ()
mutable {
214 return futurize_invoke(func).finally([&sm] {
221template <std::invocable Func>
222 requires (!std::is_nothrow_move_constructible_v<Func>)
224 futurize_t<std::invoke_result_t<Func>>
228 return do_with(std::forward<Func>(func), [&sm] (Func& func) {
229 return sm.
lock().then([&func] {
245concept FutureBasicLockable =
requires (T& t) {
246 { t.lock() } -> std::same_as<future<>>;
247 { t.unlock() }
noexcept -> std::same_as<void>;
256concept FutureBasicSharedLockable =
requires (T& t) {
257 { t.lock_shared() } -> std::same_as<future<>>;
258 { t.unlock_shared() }
noexcept -> std::same_as<void>;
271template <
internal::FutureBasicSharedLockable T>
273 co_await t.lock_shared();
276 co_return std::shared_lock<T>{t, std::adopt_lock_t{}};
291template <
internal::FutureBasicLockable T>
296 co_return std::unique_lock<T>{t, std::adopt_lock_t{}};
304SEASTAR_MODULE_EXPORT_END
A representation of a possibly not-yet-computed value.
Definition: future.hh:1240
Result then(Func &&func) noexcept
Schedule a block of code to run when the future is ready.
Definition: future.hh:1425
Shared/exclusive mutual exclusion.
Definition: shared_mutex.hh:59
void unlock_shared() noexcept
Unlocks a shared_mutex after a previous call to lock_shared().
Definition: shared_mutex.hh:100
future lock() noexcept
Definition: shared_mutex.hh:109
bool try_lock() noexcept
Definition: shared_mutex.hh:123
void unlock() noexcept
Unlocks a shared_mutex after a previous call to lock().
Definition: shared_mutex.hh:131
bool try_lock_shared() noexcept
Definition: shared_mutex.hh:92
future lock_shared() noexcept
Definition: shared_mutex.hh:78
future< std::shared_lock< T > > get_shared_lock(T &t)
Construct a RAII-based shared lock corresponding to a given object.
Definition: shared_mutex.hh:272
future< std::unique_lock< T > > get_unique_lock(T &t)
Construct a RAII-based unique lock corresponding to a given object.
Definition: shared_mutex.hh:292
futurize_t< std::invoke_result_t< Func > > with_lock(shared_mutex &sm, Func &&func) noexcept
Definition: shared_mutex.hh:212
futurize_t< std::invoke_result_t< Func > > with_shared(shared_mutex &sm, Func &&func) noexcept
Definition: shared_mutex.hh:171
future< T > current_exception_as_future() noexcept
Returns std::current_exception() wrapped in a future.
Definition: future.hh:1962
auto do_with(T1 &&rv1, T2 &&rv2, More &&... more) noexcept
Definition: do_with.hh:135
auto with_lock(Lock &lock, Func &&func)
Definition: do_with.hh:149
Seastar API namespace.
Definition: abort_on_ebadf.hh:26