Skip to content

Commit e25f9e9

Browse files
authored
Safeguard for Ticker internal storage that may be changed during callback execution (#8820)
Temporarily move callback into the function scope and execute it from there. Detaching would no longer destroy it, and re-scheduling would no longer be almost immediately cancelled by our code.
1 parent 9c4a123 commit e25f9e9

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

libraries/Ticker/src/Ticker.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,28 @@ void Ticker::_static_callback()
115115
}
116116
}
117117

118+
// it is technically allowed to call either schedule or detach
119+
// *during* callback execution. allow both to happen
120+
decltype(_callback) tmp;
121+
std::swap(tmp, _callback);
122+
118123
std::visit([](auto&& callback) {
119124
using T = std::decay_t<decltype(callback)>;
120125
if constexpr (std::is_same_v<T, callback_ptr_t>) {
121126
callback.func(callback.arg);
122127
} else if constexpr (std::is_same_v<T, callback_function_t>) {
123128
callback();
124129
}
125-
}, _callback);
130+
}, tmp);
131+
132+
// ...and move ourselves back only when object is in a valid state
133+
// * ticker was not detached, zeroing timer pointer
134+
// * nothing else replaced callback variant
135+
if ((_timer == nullptr) || !std::holds_alternative<std::monostate>(_callback)) {
136+
return;
137+
}
138+
139+
std::swap(tmp, _callback);
126140

127141
if (_repeat) {
128142
if (_tick) {

0 commit comments

Comments
 (0)