-
Notifications
You must be signed in to change notification settings - Fork 651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calling Timer::start
or Timer::stop
in the same timer's callback leads to unexpected behavior
#1532
Comments
Timer::start
in the same timer's callback leads to unexpected behaviorTimer::start
or Timer::stop
in the same timer's callback leads to unexpected behavior
tay64
added a commit
to tay64/slint
that referenced
this issue
Aug 25, 2022
…lback Before the change: - calling the_timer.start(...) in the_timer's callback resulted in the_timer keeping the old callback; - calling the_timer.stop() in the_timer's callback was ignored.
tay64
added a commit
to tay64/slint
that referenced
this issue
Aug 25, 2022
Before the change: - calling the_timer.start(...) in the_timer's callback resulted in the_timer keeping the old callback; - calling the_timer.stop() in the_timer's callback was ignored.
tay64
added a commit
to tay64/slint
that referenced
this issue
Aug 25, 2022
Before the change: - calling the_timer.start(...) in the_timer's callback resulted in the_timer keeping the old callback; - calling the_timer.stop() in the_timer's callback was ignored.
ogoffart
pushed a commit
that referenced
this issue
Aug 26, 2022
Before the change: - calling the_timer.start(...) in the_timer's callback resulted in the_timer keeping the old callback; - calling the_timer.stop() in the_timer's callback was ignored.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
Assume this pseudocode:
let the_timer = Timer::default();
the_timer.start(some_mode, some_interval, some_callback);
Undesired behaviors
If
some_callback
callsthe_timer.start(new_mode, new_interval, new_callback)
, the effect will bethe_timer
running withnew_mode
andnew_interval
, but the oldsome_callback
.Under some circumstances this leads to unobvious effects, like a single-shot timer seemingly turning into a periodic timer (see Steps to reproduce below for an example).
If
some_mode
isRepeated
andsome_callback
callsthe_timer.stop()
, the timer won't stop.Analysis
This is caused by the order of operations in
internal/core/timers.rs :: maybe_activate_timers()
; specifically, by the fact that the callback is invoked in the middle of the timer state update. As a consequence, if the callback itself modifies the timer state via the timer API, part of the modifications will be overwritten bymaybe_activate_timers()
.I have a possible fix. I will clean it up a bit and submit a PR for your consideration. (EDIT: PR #1533)
Steps to reproduce
This is not the smallest repro example, just the one I came up with while distilling the problem I encountered in my project. I decided to include it here because it demonstrates a surprising behavior that at a first glance looks as if a
SingleShot
timer turns into aRepeated
(the real explanation is that every time the first callback is invoked, it restarts the timer with the second callback, but the second callback gets overwritten with the first callback again).cargo generate --git https://github.com/slint-ui/slint-rust-template
.diff file
modified main.rs
cargo run
Expected:
Observed:
Note that starting with the 3rd line the timestamp delta is 200ms, i.e. the new interval took effect, but the wrong callback is invoked.
The text was updated successfully, but these errors were encountered: