24 #ifndef SEASTAR_MODULE
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()) {
284 #ifdef SEASTAR_GATE_HOLDER_DEBUG
285 using holders_list_t = boost::intrusive::list<holder,
286 boost::intrusive::member_hook<holder, holder::member_hook_t, &holder::_link>,
287 boost::intrusive::constant_time_size<false>>;
289 holders_list_t _holders;
293 #ifdef SEASTAR_GATE_HOLDER_DEBUG
294 SEASTAR_MODULE_EXPORT
295 inline void gate::assert_not_held_when_moved() const noexcept {
296 assert(_holders.empty() &&
"gate moved with outstanding holders");
298 inline void gate::assert_not_held_when_destroyed() const noexcept {
299 assert(_holders.empty() &&
"gate destroyed with outstanding holders");
305 template <
typename Func>
308 invoke_func_with_gate(gate::holder&& gh, Func&& func) noexcept {
309 return futurize_invoke(std::forward<Func>(func)).finally([gh = std::forward<gate::holder>(gh)] {});
322 SEASTAR_MODULE_EXPORT
323 template <
typename Func>
327 return internal::invoke_func_with_gate(g.
hold(), std::forward<Func>(func));
341 SEASTAR_MODULE_EXPORT
342 template <
typename Func>
350 return internal::invoke_func_with_gate(g.hold(), std::forward<Func>(func));
holder(gate &g)
Definition: gate.hh:209
holder & operator=(holder &&x) noexcept
Definition: gate.hh:260
~holder()
Destroy a holder and leave the referenced gate.
Definition: gate.hh:234
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 & operator=(const holder &x) noexcept
Definition: gate.hh:244
holder() noexcept
Definition: gate.hh:205
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
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:326
auto try_with_gate(gate &g, Func &&func) noexcept
Definition: gate.hh:345
future< T > make_exception_future(std::exception_ptr &&value) noexcept
Creates a future in an available, failed state.
Definition: future.hh:1940
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Converts a type to a future type, if it isn't already.
Definition: future.hh:1843