mirror of https://github.com/fltk/fltk
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.
This commit is contained in:
parent
d8eb1f9ca4
commit
f3bf231cc0
|
@ -162,9 +162,9 @@ void Fl_Timeout::repeat_timeout(double time, Fl_Timeout_Handler cb, void *data)
|
||||||
Fl_Timeout *cur = current_timeout;
|
Fl_Timeout *cur = current_timeout;
|
||||||
if (cur) {
|
if (cur) {
|
||||||
t->time += cur->time; // was: missed_timeout_by (always <= 0.0)
|
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();
|
t->insert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +245,8 @@ void Fl_Timeout::release() {
|
||||||
current_timeout = t->next;
|
current_timeout = t->next;
|
||||||
}
|
}
|
||||||
// put the timer into the list of free timers
|
// put the timer into the list of free timers
|
||||||
t->next = free_timeout;
|
next = free_timeout;
|
||||||
free_timeout = t;
|
free_timeout = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -317,6 +317,7 @@ Fl_Timeout *Fl_Timeout::get(double time, Fl_Timeout_Handler cb, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t->next = 0;
|
t->next = 0;
|
||||||
|
t->skip = 1; // see do_timeouts() (issue #450)
|
||||||
t->delay(time);
|
t->delay(time);
|
||||||
t->callback = cb;
|
t->callback = cb;
|
||||||
t->data = data;
|
t->data = data;
|
||||||
|
@ -358,11 +359,26 @@ void Fl_Timeout::elapse_timeouts() {
|
||||||
Elapse timers and call their callbacks if any timers are expired.
|
Elapse timers and call their callbacks if any timers are expired.
|
||||||
*/
|
*/
|
||||||
void Fl_Timeout::do_timeouts() {
|
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) {
|
if (first_timeout) {
|
||||||
Fl_Timeout::elapse_timeouts();
|
Fl_Timeout::elapse_timeouts();
|
||||||
Fl_Timeout *t;
|
while ((t = first_timeout)) {
|
||||||
while ((t = Fl_Timeout::first_timeout)) {
|
|
||||||
if (t->time > 0) break;
|
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
|
// make this timeout the "current" timeout
|
||||||
t->make_current();
|
t->make_current();
|
||||||
// now it is safe for the callback to do add_timeout:
|
// now it is safe for the callback to do add_timeout:
|
||||||
|
|
|
@ -51,6 +51,7 @@ protected:
|
||||||
Fl_Timeout_Handler callback; // the user's callback
|
Fl_Timeout_Handler callback; // the user's callback
|
||||||
void *data; // the user's callback data
|
void *data; // the user's callback data
|
||||||
double time; // delay until timeout
|
double time; // delay until timeout
|
||||||
|
int skip; // skip "new" (inserted) timers (issue #450)
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
Fl_Timeout() {
|
Fl_Timeout() {
|
||||||
|
@ -58,6 +59,7 @@ protected:
|
||||||
callback = 0;
|
callback = 0;
|
||||||
data = 0;
|
data = 0;
|
||||||
time = 0;
|
time = 0;
|
||||||
|
skip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Fl_Timeout() {}
|
~Fl_Timeout() {}
|
||||||
|
|
Loading…
Reference in New Issue