mirror of
https://github.com/cesanta/mongoose.git
synced 2025-06-07 17:42:30 +08:00
Fix #2768 - remove completed timers
This commit is contained in:
parent
40a2a8822f
commit
0539cf1023
12
mongoose.c
12
mongoose.c
@ -4017,8 +4017,8 @@ struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
||||
unsigned flags, void (*fn)(void *), void *arg) {
|
||||
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
||||
if (t != NULL) {
|
||||
flags |= MG_TIMER_AUTODELETE; // We have calloc-ed it, so autodelete
|
||||
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
||||
t->id = mgr->timerid++;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
@ -9131,11 +9131,9 @@ bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) {
|
||||
|
||||
|
||||
|
||||
#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) {
|
||||
t->id = 0, t->period_ms = ms, t->expire = 0;
|
||||
t->period_ms = ms, t->expire = 0;
|
||||
t->flags = flags, t->fn = fn, t->arg = arg, t->next = *head;
|
||||
*head = t;
|
||||
}
|
||||
@ -9166,6 +9164,12 @@ void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
|
||||
t->fn(t->arg);
|
||||
}
|
||||
t->flags |= MG_TIMER_CALLED;
|
||||
|
||||
// If this timer is not repeating and marked AUTODELETE, remove it
|
||||
if (!(t->flags & MG_TIMER_REPEAT) && (t->flags & MG_TIMER_AUTODELETE)) {
|
||||
mg_timer_free(head, t);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
22
mongoose.h
22
mongoose.h
@ -1020,16 +1020,17 @@ void mg_log_set_fn(mg_pfn_t fn, void *param);
|
||||
|
||||
|
||||
struct mg_timer {
|
||||
unsigned long id; // Timer ID
|
||||
uint64_t period_ms; // Timer period in milliseconds
|
||||
uint64_t expire; // Expiration timestamp in milliseconds
|
||||
unsigned flags; // Possible flags values below
|
||||
#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
|
||||
uint64_t period_ms; // Timer period in milliseconds
|
||||
uint64_t expire; // Expiration timestamp in milliseconds
|
||||
unsigned flags; // Possible flags values below
|
||||
#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
|
||||
#define MG_TIMER_CALLED 4 // Timer function was called at least once
|
||||
#define MG_TIMER_AUTODELETE 8 // free() timer when done
|
||||
void (*fn)(void *); // Function to call
|
||||
void *arg; // Function argument
|
||||
struct mg_timer *next; // Linkage
|
||||
};
|
||||
|
||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
||||
@ -2208,7 +2209,6 @@ struct mg_mgr {
|
||||
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||
bool use_dns6; // Use DNS6 server by default, see #1532
|
||||
unsigned long nextid; // Next connection ID
|
||||
unsigned long timerid; // Next timer ID
|
||||
void *userdata; // Arbitrary user data pointer
|
||||
void *tls_ctx; // TLS context shared by all TLS sessions
|
||||
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "net.h"
|
||||
#include "dns.h"
|
||||
#include "fmt.h"
|
||||
#include "log.h"
|
||||
#include "net.h"
|
||||
#include "printf.h"
|
||||
#include "profile.h"
|
||||
#include "timer.h"
|
||||
@ -218,8 +218,8 @@ struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
||||
unsigned flags, void (*fn)(void *), void *arg) {
|
||||
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
||||
if (t != NULL) {
|
||||
flags |= MG_TIMER_AUTODELETE; // We have calloc-ed it, so autodelete
|
||||
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
||||
t->id = mgr->timerid++;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ struct mg_mgr {
|
||||
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||
bool use_dns6; // Use DNS6 server by default, see #1532
|
||||
unsigned long nextid; // Next connection ID
|
||||
unsigned long timerid; // Next timer ID
|
||||
void *userdata; // Arbitrary user data pointer
|
||||
void *tls_ctx; // TLS context shared by all TLS sessions
|
||||
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
||||
|
12
src/timer.c
12
src/timer.c
@ -1,11 +1,9 @@
|
||||
#include "timer.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define MG_TIMER_CALLED 4
|
||||
#include "timer.h"
|
||||
|
||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
|
||||
unsigned flags, void (*fn)(void *), void *arg) {
|
||||
t->id = 0, t->period_ms = ms, t->expire = 0;
|
||||
t->period_ms = ms, t->expire = 0;
|
||||
t->flags = flags, t->fn = fn, t->arg = arg, t->next = *head;
|
||||
*head = t;
|
||||
}
|
||||
@ -36,5 +34,11 @@ void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
|
||||
t->fn(t->arg);
|
||||
}
|
||||
t->flags |= MG_TIMER_CALLED;
|
||||
|
||||
// If this timer is not repeating and marked AUTODELETE, remove it
|
||||
if (!(t->flags & MG_TIMER_REPEAT) && (t->flags & MG_TIMER_AUTODELETE)) {
|
||||
mg_timer_free(head, t);
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
src/timer.h
21
src/timer.h
@ -3,16 +3,17 @@
|
||||
#include "arch.h"
|
||||
|
||||
struct mg_timer {
|
||||
unsigned long id; // Timer ID
|
||||
uint64_t period_ms; // Timer period in milliseconds
|
||||
uint64_t expire; // Expiration timestamp in milliseconds
|
||||
unsigned flags; // Possible flags values below
|
||||
#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
|
||||
uint64_t period_ms; // Timer period in milliseconds
|
||||
uint64_t expire; // Expiration timestamp in milliseconds
|
||||
unsigned flags; // Possible flags values below
|
||||
#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
|
||||
#define MG_TIMER_CALLED 4 // Timer function was called at least once
|
||||
#define MG_TIMER_AUTODELETE 8 // free() timer when done
|
||||
void (*fn)(void *); // Function to call
|
||||
void *arg; // Function argument
|
||||
struct mg_timer *next; // Linkage
|
||||
};
|
||||
|
||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
||||
|
@ -1960,6 +1960,22 @@ static void test_timer(void) {
|
||||
ASSERT(mgr.timers == NULL);
|
||||
ASSERT(mgr.conns == NULL);
|
||||
}
|
||||
|
||||
// Test that non-repeating called timers are deleted, see #2768
|
||||
{
|
||||
struct mg_mgr mgr;
|
||||
int arg = 0;
|
||||
mg_mgr_init(&mgr);
|
||||
mg_timer_add(&mgr, 0, MG_TIMER_ONCE, f1, &arg);
|
||||
ASSERT(mgr.timers != NULL);
|
||||
mg_mgr_poll(&mgr, 10);
|
||||
ASSERT(arg == 1);
|
||||
ASSERT(mgr.timers == NULL);
|
||||
mg_mgr_free(&mgr);
|
||||
ASSERT(mgr.timers == NULL);
|
||||
ASSERT(mgr.conns == NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool sn(const char *fmt, ...) {
|
||||
|
Loading…
Reference in New Issue
Block a user