This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository e16.
View the commit online.
commit 6a0c30e77ff598e90d38dd3c58f4552a996ab4b5
Author: Kim Woelders <[email protected]>
AuthorDate: Sun Oct 30 10:01:42 2022 +0100
timers: Properly fix timer lockup issue
Adding timers from within timer callback functions could cause lockups
and memory leaks.
---
src/timers.c | 43 +++++++++++++++++++++++++++++++++++--------
1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/src/timers.c b/src/timers.c
index 883ed001..ed482d56 100644
--- a/src/timers.c
+++ b/src/timers.c
@@ -25,6 +25,13 @@
#include "list.h"
#include "timers.h"
+#define DEBUG_TIMERS 0
+#if DEBUG_TIMERS
+#define Dprintf(fmt...) if(EDebug(EDBUG_TYPE_TIMERS))Eprintf(fmt)
+#else
+#define Dprintf(fmt...)
+#endif
+
struct _timer {
unsigned int in_time;
unsigned int at_time;
@@ -109,14 +116,19 @@ TimerAdd(int dt_ms, int (*func)(void *data), void *data)
void
TimersRun(unsigned int t_ms)
{
- Timer *timer, *q_old, *q_run;
+ Timer *timer, *q_old, *q_new, *q_run;
timer = q_first;
if (!timer)
return; /* No timers pending */
- q_run = q_old = timer;
- for (; timer; timer = q_first)
+ Dprintf("%s - A\n", __func__);
+
+ q_new = timer; /* q_new is now temporarily the timer queue */
+ q_old = timer; /* q_old is the old timer queue */
+ q_first = NULL; /* q_first holds timers added during timer processing */
+ q_run = NULL; /* q_run holds the last run timer */
+ for (; timer; timer = q_new)
{
if (tdiff(timer->at_time, t_ms) > 0)
break;
@@ -125,23 +137,25 @@ TimersRun(unsigned int t_ms)
Eprintf("%s - run %p: func=%p data="" %8d\n", __func__, timer,
timer->func, timer->data, timer->at_time - t_ms);
- q_first = timer->next;
+ q_new = timer->next;
/* Run this callback */
timer->again = timer->func(timer->data);
q_run = timer;
}
- if (q_old != q_first)
+ if (q_run)
{
/* At least one timer has run */
q_run->next = NULL; /* Terminate expired timer list */
/* Re-schedule/remove timers that have run */
- for (timer = q_old; timer; timer = q_old)
+ q_run = q_new; /* Swap q_first and q_new ... */
+ q_new = q_first; /* q_new are the new added timers */
+ q_first = q_run; /* q_first is now the timer queue */
+ for (timer = q_old; timer; timer = q_run)
{
- q_old = timer->next;
- timer->next = NULL;
+ q_run = timer->next;
if (timer->again)
{
timer->at_time += timer->in_time;
@@ -152,6 +166,17 @@ TimersRun(unsigned int t_ms)
_TimerDel(timer);
}
}
+
+ /* Schedule timers that have been added */
+ for (timer = q_new; timer; timer = q_run)
+ {
+ q_run = timer->next;
+ _TimerSet(timer); /* Add to timer queue */
+ }
+ }
+ else
+ {
+ q_first = q_old; /* Restore timer queue */
}
if (EDebug(EDBUG_TYPE_TIMERS) > 1)
@@ -161,6 +186,8 @@ TimersRun(unsigned int t_ms)
timer, timer->func, timer->data, timer->at_time - t_ms,
timer->in_time);
}
+
+ Dprintf("%s - B\n", __func__);
}
int
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.