25#include <boost/intrusive/list.hpp>
27#include <seastar/core/future.hh>
28#include <seastar/util/std-compat.hh>
29#include <seastar/util/modules.hh>
37#define SEASTAR_GATE_HOLDER_DEBUG
50 virtual const char* what()
const noexcept override {
63 std::optional<promise<>> _stopped;
65#ifdef SEASTAR_GATE_HOLDER_DEBUG
66 void assert_not_held_when_moved()
const noexcept;
67 void assert_not_held_when_destroyed()
const noexcept;
69 void assert_not_held_when_moved()
const noexcept {}
70 void assert_not_held_when_destroyed()
const noexcept {}
78 : _count(std::exchange(x._count, 0)), _stopped(std::exchange(x._stopped, std::nullopt)) {
79 x.assert_not_held_when_moved();
83 assert(!_count &&
"gate reassigned with outstanding requests");
84 x.assert_not_held_when_moved();
85 _count = std::exchange(x._count, 0);
86 _stopped = std::exchange(x._stopped, std::nullopt);
91 assert(!_count &&
"gate destroyed with outstanding requests");
92 assert_not_held_when_destroyed();
99 bool opened = !_stopped;
120 if (!_count && _stopped) {
121 _stopped->set_value();
144 assert(!_stopped &&
"seastar::gate::close() cannot be called more than once");
145 _stopped = std::make_optional(
promise<>());
147 _stopped->set_value();
149 return _stopped->get_future();
159 return bool(_stopped);
173#ifdef SEASTAR_GATE_HOLDER_DEBUG
174 using member_hook_t = boost::intrusive::list_member_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>;
177 void debug_hold_gate()
noexcept {
179 _g->_holders.push_back(*
this);
183 void debug_release_gate()
noexcept {
187 void debug_hold_gate()
noexcept {}
188 void debug_release_gate()
noexcept {}
193 gate* release_gate()
noexcept {
194 auto* g = std::exchange(_g,
nullptr);
196 debug_release_gate();
263 _g = std::move(x).release_gate();
271 if (
auto g = release_gate()) {
287 return is_closed() ? std::nullopt : std::make_optional<holder>(*
this);
291#ifdef SEASTAR_GATE_HOLDER_DEBUG
292 using holders_list_t = boost::intrusive::list<holder,
293 boost::intrusive::member_hook<holder, holder::member_hook_t, &holder::_link>,
294 boost::intrusive::constant_time_size<false>>;
296 holders_list_t _holders;
300#ifdef SEASTAR_GATE_HOLDER_DEBUG
302inline void gate::assert_not_held_when_moved() const noexcept {
303 assert(_holders.empty() &&
"gate moved with outstanding holders");
305inline void gate::assert_not_held_when_destroyed() const noexcept {
306 assert(_holders.empty() &&
"gate destroyed with outstanding holders");
312template <
typename Func>
315invoke_func_with_gate(gate::holder&& gh, Func&& func)
noexcept {
316 return futurize_invoke(std::forward<Func>(func)).finally([gh = std::forward<gate::holder>(gh)] {});
330template <
typename Func>
334 return internal::invoke_func_with_gate(g.
hold(), std::forward<Func>(func));
349template <
typename Func>
357 return internal::invoke_func_with_gate(g.hold(), std::forward<Func>(func));
A representation of a possibly not-yet-computed value.
Definition: future.hh:1240
holder(gate &g)
Definition: gate.hh:209
~holder()
Destroy a holder and leave the referenced gate.
Definition: gate.hh:234
holder & operator=(const holder &x) noexcept
Definition: gate.hh:244
holder(holder &&x) noexcept
Definition: gate.hh:229
holder(const holder &x) noexcept
Definition: gate.hh:219
void release() noexcept
Leave the held gate.
Definition: gate.hh:270
holder() noexcept
Definition: gate.hh:205
holder & operator=(holder &&x) noexcept
Definition: gate.hh:260
bool try_enter() noexcept
Definition: gate.hh:98
bool is_closed() const noexcept
Returns whether the gate is closed.
Definition: gate.hh:158
future close() noexcept
Definition: gate.hh:143
size_t get_count() const noexcept
Returns a current number of registered in-progress requests.
Definition: gate.hh:153
void check()
Definition: gate.hh:133
std::optional< holder > try_hold() noexcept
Definition: gate.hh:286
holder hold()
Definition: gate.hh:279
void enter()
Definition: gate.hh:109
void leave() noexcept
Definition: gate.hh:118
auto with_gate(gate &g, Func &&func)
Definition: gate.hh:333
auto try_with_gate(gate &g, Func &&func) noexcept
Definition: gate.hh:352
future< T > make_exception_future(std::exception_ptr &&value) noexcept
Creates a future in an available, failed state.
Definition: future.hh:1949
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Converts a type to a future type, if it isn't already.
Definition: future.hh:1853