| [ Return to Bugs & Features | Roadmap 1.3 | SVN ⇄ GIT ]
STR #3532
Application: | FLTK Library |
Status: | 1 - Closed w/Resolution |
Priority: | 3 - Moderate, e.g. unable to compile the software |
Scope: | 2 - Specific to an operating system |
Subsystem: | Core Library |
Summary: | timeout set by Fl::add_timeout elapses too early |
Version: | 1.3.5 |
Created By: | meixner |
Assigned To: | AlbrechtS |
Fix Version: | 1.4.0 |
Fix Commit: | 3b249de60a99e639704ce8dba77e593c7c07aec1 |
Update Notification: | |
Trouble Report Files:
No files
Trouble Report Comments:
|
#1 | meixner 02:29 Jan 17, 2020 |
| A timeout set by Fl::add_timeout elapses too early, if a previous timeout was processed with delay.
The reason is that add_timeout() internally uses repeat_timeout() to add the new timeout but repeat_timeout() adds missed_timeout_by to the selected timeout, which is wrong in case of add_timeout(). If the last timeout was processed with delay, the timeout set by add_timeout() will elapse too early.
Changing add_timeout in Fl.cxx as follows fixes the issue:
void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) { elapse_timeouts(); double miss=missed_timeout_by; missed_timeout_by=0; repeat_timeout(time, cb, argp); missed_timeout_by=miss; } | |
|
#2 | AlbrechtS 12:18 Jan 18, 2020 |
| Thanks for the report. Indeed, this is true (Linux/Unix only) and has been fixed in FLTK 1.4 (Git master, commit 35a3e7cc16f8) but not backported. See also STR #3516 (which is about more than only this aspect).
The fix in FLTK 1.4 was to just clear 'missed_timeout_by' w/o saving and restoring the value (as you propose) because it seems to be unnecessary. It was a fault not to clear the missed_timeout_by value at all (except overwriting it when serving the next timeout).
Do you have evidence that the value should be saved and restored, or was this only kinda "defensive programming"?
I'm not sure if we should backport this to 1.3: after all it's not a serious bug, it's only prio 3 (moderate). | |
|
#3 | meixner 23:34 Jan 19, 2020 |
| I just stored it to not have to think about what would happen if I reset it.
However, thinking about it now, what would happen, if you have something like:
void callback1(void *data) { Fl::add_timeout(0.1,callback2,0); Fl::repeat_timeout(1,callback1,0); }
I guess in this case repeat_timeout would not work as expected any longer since the call to add_timeout would reset missed_timeout_by. | |
|
#4 | AlbrechtS 02:19 Jan 20, 2020 |
| Thanks for your comment.
Your comment is absolutely correct, but this would be some kind of "undefined behavior" (and usage).
Basically the "missed_by" mechanism can only work correctly (as intended) if you call Fl::repeat_timeout() with the same callback that triggered it - otherwise 'missed_by' must be considered just a random (undefined) value. Strictly spoken, the timeout you start with Fl::repeat_timeout() need not be exactly the same callback but it must be directly related to the timeout being served.
That said, Fl::repeat_timeout() must only be called
(a) within a callback triggered by Fl::add/repeat_timeout and (b) with the same or a directly related timer
I believe the documentation needs to be clarified...
This is a task to be done in FLTK 1.4, hence I tend to close this STR w/o backporting anything to FLTK 1.3. | |
|
#5 | AlbrechtS 06:30 Jun 30, 2020 |
| Fixed in Git repository.
Documentation has been clarified. No further code changes required.
Closing this STR now. | |
[ Return to Bugs & Features ]
|
| |