mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-18 10:59:45 +00:00
Address #1551 - better timers handling
This commit is contained in:
1 parent
443d0f0c6c
commit
cf7d1d8041
6 files changed
+48
-38
No files matched your search
+12
-4
@@ -4,12 +4,13 @@
|
||||
#include "timer.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define MG_TIMER_CALLED 4
|
||||
|
||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
|
||||
unsigned flags, void (*fn)(void *), void *arg) {
|
||||
struct mg_timer tmp = {ms, 0U, 0U, flags, fn, arg, *head};
|
||||
*t = tmp;
|
||||
*head = t;
|
||||
if (flags & MG_TIMER_RUN_NOW) fn(arg);
|
||||
}
|
||||
|
||||
void mg_timer_free(struct mg_timer **head, struct mg_timer *t) {
|
||||
@@ -24,13 +25,20 @@ void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
|
||||
tmp = t->next;
|
||||
if (t->prev_ms > now_ms) t->expire = 0; // Handle time wrap
|
||||
t->prev_ms = now_ms;
|
||||
if (t->expire == 0) t->expire = now_ms + t->period_ms;
|
||||
if (t->expire == 0 && (t->flags & MG_TIMER_RUN_NOW) &&
|
||||
!(t->flags & MG_TIMER_CALLED)) {
|
||||
// Handle MG_TIMER_NOW only once
|
||||
} else if (t->expire == 0) {
|
||||
t->expire = now_ms + t->period_ms;
|
||||
}
|
||||
if (t->expire > now_ms) continue;
|
||||
t->fn(t->arg);
|
||||
if ((t->flags & MG_TIMER_REPEAT) || !(t->flags & MG_TIMER_CALLED)) {
|
||||
t->fn(t->arg);
|
||||
}
|
||||
t->flags |= MG_TIMER_CALLED;
|
||||
// Try to tick timers with the given period as accurate as possible,
|
||||
// even if this polling function is called with some random period.
|
||||
t->expire = now_ms - t->expire > t->period_ms ? now_ms + t->period_ms
|
||||
: t->expire + t->period_ms;
|
||||
if (!(t->flags & MG_TIMER_REPEAT)) mg_timer_free(head, t);
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -7,15 +7,14 @@ struct mg_timer {
|
||||
uint64_t prev_ms; // Timestamp of a previous poll
|
||||
uint64_t expire; // Expiration timestamp in milliseconds
|
||||
unsigned flags; // Possible flags values below
|
||||
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
|
||||
#define MG_TIMER_ONCE 0 // Call function once
|
||||
#define MG_TIMER_REPEAT 1 // Call function periodically
|
||||
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
||||
void (*fn)(void *); // Function to call
|
||||
void *arg; // Function argument
|
||||
struct mg_timer *next; // Linkage in g_timers list
|
||||
struct mg_timer *next; // Linkage
|
||||
};
|
||||
|
||||
extern struct mg_timer *g_timers; // Global list of timers
|
||||
|
||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
||||
uint64_t milliseconds, unsigned flags, void (*fn)(void *),
|
||||
void *arg);
|
||||
|
||||
Reference in new issue
Block a user