mirror of
https://github.com/cesanta/mongoose.git
synced 2025-06-08 01:42:52 +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) {
|
unsigned flags, void (*fn)(void *), void *arg) {
|
||||||
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
||||||
if (t != NULL) {
|
if (t != NULL) {
|
||||||
|
flags |= MG_TIMER_AUTODELETE; // We have calloc-ed it, so autodelete
|
||||||
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
||||||
t->id = mgr->timerid++;
|
|
||||||
}
|
}
|
||||||
return t;
|
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,
|
void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
|
||||||
unsigned flags, void (*fn)(void *), void *arg) {
|
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;
|
t->flags = flags, t->fn = fn, t->arg = arg, t->next = *head;
|
||||||
*head = t;
|
*head = t;
|
||||||
}
|
}
|
||||||
@ -9166,6 +9164,12 @@ void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
|
|||||||
t->fn(t->arg);
|
t->fn(t->arg);
|
||||||
}
|
}
|
||||||
t->flags |= MG_TIMER_CALLED;
|
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 {
|
struct mg_timer {
|
||||||
unsigned long id; // Timer ID
|
uint64_t period_ms; // Timer period in milliseconds
|
||||||
uint64_t period_ms; // Timer period in milliseconds
|
uint64_t expire; // Expiration timestamp in milliseconds
|
||||||
uint64_t expire; // Expiration timestamp in milliseconds
|
unsigned flags; // Possible flags values below
|
||||||
unsigned flags; // Possible flags values below
|
#define MG_TIMER_ONCE 0 // Call function once
|
||||||
#define MG_TIMER_ONCE 0 // Call function once
|
#define MG_TIMER_REPEAT 1 // Call function periodically
|
||||||
#define MG_TIMER_REPEAT 1 // Call function periodically
|
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
||||||
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
#define MG_TIMER_CALLED 4 // Timer function was called at least once
|
||||||
void (*fn)(void *); // Function to call
|
#define MG_TIMER_AUTODELETE 8 // free() timer when done
|
||||||
void *arg; // Function argument
|
void (*fn)(void *); // Function to call
|
||||||
struct mg_timer *next; // Linkage
|
void *arg; // Function argument
|
||||||
|
struct mg_timer *next; // Linkage
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
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
|
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||||
bool use_dns6; // Use DNS6 server by default, see #1532
|
bool use_dns6; // Use DNS6 server by default, see #1532
|
||||||
unsigned long nextid; // Next connection ID
|
unsigned long nextid; // Next connection ID
|
||||||
unsigned long timerid; // Next timer ID
|
|
||||||
void *userdata; // Arbitrary user data pointer
|
void *userdata; // Arbitrary user data pointer
|
||||||
void *tls_ctx; // TLS context shared by all TLS sessions
|
void *tls_ctx; // TLS context shared by all TLS sessions
|
||||||
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "net.h"
|
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "net.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
#include "timer.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) {
|
unsigned flags, void (*fn)(void *), void *arg) {
|
||||||
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
||||||
if (t != NULL) {
|
if (t != NULL) {
|
||||||
|
flags |= MG_TIMER_AUTODELETE; // We have calloc-ed it, so autodelete
|
||||||
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
||||||
t->id = mgr->timerid++;
|
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ struct mg_mgr {
|
|||||||
int dnstimeout; // DNS resolve timeout in milliseconds
|
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||||
bool use_dns6; // Use DNS6 server by default, see #1532
|
bool use_dns6; // Use DNS6 server by default, see #1532
|
||||||
unsigned long nextid; // Next connection ID
|
unsigned long nextid; // Next connection ID
|
||||||
unsigned long timerid; // Next timer ID
|
|
||||||
void *userdata; // Arbitrary user data pointer
|
void *userdata; // Arbitrary user data pointer
|
||||||
void *tls_ctx; // TLS context shared by all TLS sessions
|
void *tls_ctx; // TLS context shared by all TLS sessions
|
||||||
uint16_t mqtt_id; // MQTT IDs for pub/sub
|
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"
|
#include "arch.h"
|
||||||
|
#include "timer.h"
|
||||||
#define MG_TIMER_CALLED 4
|
|
||||||
|
|
||||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
|
void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
|
||||||
unsigned flags, void (*fn)(void *), void *arg) {
|
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;
|
t->flags = flags, t->fn = fn, t->arg = arg, t->next = *head;
|
||||||
*head = t;
|
*head = t;
|
||||||
}
|
}
|
||||||
@ -36,5 +34,11 @@ void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
|
|||||||
t->fn(t->arg);
|
t->fn(t->arg);
|
||||||
}
|
}
|
||||||
t->flags |= MG_TIMER_CALLED;
|
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"
|
#include "arch.h"
|
||||||
|
|
||||||
struct mg_timer {
|
struct mg_timer {
|
||||||
unsigned long id; // Timer ID
|
uint64_t period_ms; // Timer period in milliseconds
|
||||||
uint64_t period_ms; // Timer period in milliseconds
|
uint64_t expire; // Expiration timestamp in milliseconds
|
||||||
uint64_t expire; // Expiration timestamp in milliseconds
|
unsigned flags; // Possible flags values below
|
||||||
unsigned flags; // Possible flags values below
|
#define MG_TIMER_ONCE 0 // Call function once
|
||||||
#define MG_TIMER_ONCE 0 // Call function once
|
#define MG_TIMER_REPEAT 1 // Call function periodically
|
||||||
#define MG_TIMER_REPEAT 1 // Call function periodically
|
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
||||||
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
#define MG_TIMER_CALLED 4 // Timer function was called at least once
|
||||||
void (*fn)(void *); // Function to call
|
#define MG_TIMER_AUTODELETE 8 // free() timer when done
|
||||||
void *arg; // Function argument
|
void (*fn)(void *); // Function to call
|
||||||
struct mg_timer *next; // Linkage
|
void *arg; // Function argument
|
||||||
|
struct mg_timer *next; // Linkage
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_timer_init(struct mg_timer **head, struct mg_timer *timer,
|
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.timers == NULL);
|
||||||
ASSERT(mgr.conns == 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, ...) {
|
static bool sn(const char *fmt, ...) {
|
||||||
|
Loading…
Reference in New Issue
Block a user