18 constexpr static u8 stop_flag = 1;
19 constexpr static u8 locked_flag = 2;
32 if (!lock_unless_stopped(
true)) {
41 while (!m_callbacks.empty()) {
42 auto& callback = *m_callbacks.front();
46 bool did_destroy_itself =
false;
47 callback.m_did_destruct_in_same_thread.store(util::addressof(did_destroy_itself),
MemoryOrder::Relaxed);
50 m_callbacks.pop_front();
60 if (!did_destroy_itself) {
74 if (!lock_unless_stopped(
false)) {
78 m_callbacks.push_front(*callback);
84 void remove_callback(detail::InPlaceStopCallbackBase* callback)
const {
86 if (lock_unless_stopped(
false)) {
87 m_callbacks.erase(*callback);
96 auto stopper_thread = m_stopper_thread;
97 auto* did_destruct_in_same_thread = callback->m_did_destruct_in_same_thread.load(
MemoryOrder::Relaxed);
98 bool going_to_be_executed = !!did_destruct_in_same_thread;
101 if (!going_to_be_executed) {
102 m_callbacks.erase(*callback);
108 if (going_to_be_executed) {
112 *did_destruct_in_same_thread =
true;
122 auto lock_unless_stopped(
bool set_stop)
const ->
bool {
123 u8 flags = set_stop ? (stop_flag | locked_flag) : locked_flag;
128 if (expected & stop_flag) {
139 void lock(
bool set_stop)
const {
140 u8 flags = set_stop ? (stop_flag | locked_flag) : locked_flag;
146 void unlock(
bool set_stop)
const {
147 u8 flags = set_stop ? stop_flag : 0;
151 mutable container::IntrusiveList<detail::InPlaceStopCallbackBase> m_callbacks;
152 mutable Atomic<u8> m_state { 0 };