FLTK logo

[master] f3bf231 - Improve reliability of timeout handling (#450, part 1)

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] f3bf231 - Improve reliability of timeout handling (#450, part 1) "Albrecht Schlosser" Jun 17, 2022  
 
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 ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.