|
|
commit f3bf231cc06ab82576b798a1f615981924a2903c
Author: Albrecht Schlosser <albrechts.fltk@online.de>
AuthorDate: Fri Jun 17 17:05:10 2022 +0200
Commit: Albrecht Schlosser <albrechts.fltk@online.de>
CommitDate: Fri Jun 17 17:05:10 2022 +0200
Improve reliability of timeout handling (#450, part 1)
This commit prevents "timer loops" without intermediate event handling
if callback handling takes longer than the timer delay of repeating
timers.
For more details see GitHub issue #450.
src/Fl_Timeout.cxx | 28 ++++++++++++++++++++++------
src/Fl_Timeout.h | 2 ++
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git src/Fl_Timeout.cxx src/Fl_Timeout.cxx
index 2120046..f93b863 100644
--- src/Fl_Timeout.cxx
+++ src/Fl_Timeout.cxx
@@ -162,9 +162,9 @@ void Fl_Timeout::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data)
Fl_Timeout *cur = current_timeout;
if (cur) {
t->time += cur->time; // was: missed_timeout_by (always <= 0.0)
+ if (t->time < 0.0)
+ t->time = 0.001; // at least 1 ms
}
- if (t->time < 0.0)
- t->time = 0.001; // at least 1 ms
t->insert();
}
@@ -245,8 +245,8 @@ void Fl_Timeout::release() {
current_timeout = t->next;
}
// put the timer into the list of free timers
- t->next = free_timeout;
- free_timeout = t;
+ next = free_timeout;
+ free_timeout = this;
}
/**
@@ -317,6 +317,7 @@ Fl_Timeout *Fl_Timeout::get(double time, Fl_Timeout_Handler cb, void *data) {
}
t->next = 0;
+ t->skip = 1; // see do_timeouts() (issue #450)
t->delay(time);
t->callback = cb;
t->data = data;
@@ -358,11 +359,26 @@ void Fl_Timeout::elapse_timeouts() {
Elapse timers and call their callbacks if any timers are expired.
*/
void Fl_Timeout::do_timeouts() {
+
+ // Reset "skip" flag for existing timers (issue #450).
+ // For timers inserted in timer callbacks 'skip' will be true (1)
+
+ Fl_Timeout *t = first_timeout;
+ while (t) {
+ t->skip = 0;
+ t = t->next;
+ }
+
if (first_timeout) {
Fl_Timeout::elapse_timeouts();
- Fl_Timeout *t;
- while ((t = Fl_Timeout::first_timeout)) {
+ while ((t = first_timeout)) {
if (t->time > 0) break;
+
+ // skip timers inserted during timeout handling (issue #450)
+ while (t && t->skip)
+ t = t->next;
+ if (!t || t->time > 0) break;
+
// make this timeout the "current" timeout
t->make_current();
// now it is safe for the callback to do add_timeout:
diff --git src/Fl_Timeout.h src/Fl_Timeout.h
index 610f000..8cff846 100644
--- src/Fl_Timeout.h
+++ src/Fl_Timeout.h
@@ -51,6 +51,7 @@ protected:
Fl_Timeout_Handler callback; // the user's callback
void *data; // the user's callback data
double time; // delay until timeout
+ int skip; // skip "new" (inserted) timers (issue #450)
// constructor
Fl_Timeout() {
@@ -58,6 +59,7 @@ protected:
callback = 0;
data = 0;
time = 0;
+ skip = 0;
}
~Fl_Timeout() {}
[ Direct Link to Message ] | |
|
| |