@@ -58,7 +58,7 @@ struct timer_data {
58
58
static struct timer_data * s_timer_data = NULL ;
59
59
static struct mgos_rlock_type * s_timer_data_lock = NULL ;
60
60
61
- static void schedule_next_timer (struct timer_data * td ) {
61
+ static void schedule_next_timer (struct timer_data * td , double now ) {
62
62
struct timer_info * ti ;
63
63
struct timer_info * min_ti = NULL ;
64
64
LIST_FOREACH (ti , & td -> timers , entries ) {
@@ -67,7 +67,12 @@ static void schedule_next_timer(struct timer_data *td) {
67
67
}
68
68
}
69
69
td -> current = min_ti ;
70
- td -> nc -> ev_timer_time = (min_ti != NULL ? min_ti -> next_invocation : 0 );
70
+ if (min_ti != NULL ) {
71
+ double diff = min_ti -> next_invocation - now ;
72
+ td -> nc -> ev_timer_time = mg_time () + diff ;
73
+ } else {
74
+ td -> nc -> ev_timer_time = 0 ;
75
+ }
71
76
}
72
77
73
78
static void mgos_timer_ev (struct mg_connection * nc , int ev , void * ev_data ,
@@ -80,11 +85,11 @@ static void mgos_timer_ev(struct mg_connection *nc, int ev, void *ev_data,
80
85
struct timer_data * td = (struct timer_data * ) user_data ;
81
86
struct timer_info * ti = td -> current ;
82
87
/* Current can be NULL if it was the first to fire but was cleared. */
83
- if (ti != NULL ) {
88
+ const double now = mgos_uptime ();
89
+ if (ti != NULL && ti -> next_invocation <= now ) {
84
90
cb = ti -> cb ;
85
91
cb_arg = ti -> cb_arg ;
86
92
if (ti -> interval_ms >= 0 ) {
87
- const double now = mg_time ();
88
93
const double intvl = (ti -> interval_ms / 1000.0 );
89
94
ti -> next_invocation += intvl ;
90
95
/* Polling loop was delayed, re-sync the invocation. */
@@ -94,7 +99,7 @@ static void mgos_timer_ev(struct mg_connection *nc, int ev, void *ev_data,
94
99
LIST_REMOVE (ti , entries );
95
100
}
96
101
}
97
- schedule_next_timer (td );
102
+ schedule_next_timer (td , now );
98
103
mgos_runlock (s_timer_data_lock );
99
104
if (ti != NULL ) free (ti );
100
105
}
@@ -112,17 +117,18 @@ mgos_timer_id mgos_set_timer(int msecs, int flags, timer_callback cb,
112
117
} else {
113
118
ti -> interval_ms = -1 ;
114
119
}
120
+ double now = mgos_uptime ();
115
121
if (flags & MGOS_TIMER_RUN_NOW ) {
116
122
ti -> next_invocation = 1 ;
117
123
} else {
118
- ti -> next_invocation = mg_time () + msecs / 1000.0 ;
124
+ ti -> next_invocation = now + msecs / 1000.0 ;
119
125
}
120
126
ti -> cb = cb ;
121
127
ti -> cb_arg = arg ;
122
128
{
123
129
mgos_rlock (s_timer_data_lock );
124
130
LIST_INSERT_HEAD (& s_timer_data -> timers , ti , entries );
125
- schedule_next_timer (s_timer_data );
131
+ schedule_next_timer (s_timer_data , now );
126
132
mgos_runlock (s_timer_data_lock );
127
133
}
128
134
mongoose_schedule_poll (false /* from_isr */ );
@@ -142,7 +148,7 @@ static void mgos_clear_sw_timer(mgos_timer_id id) {
142
148
}
143
149
LIST_REMOVE (ti , entries );
144
150
if (s_timer_data -> current == ti ) {
145
- schedule_next_timer (s_timer_data );
151
+ schedule_next_timer (s_timer_data , mgos_uptime () );
146
152
/* Removing a timer can only push back invocation, no need to do a poll. */
147
153
}
148
154
mgos_runlock (s_timer_data_lock );
@@ -180,16 +186,16 @@ bool mgos_get_timer_info(mgos_timer_id id, struct mgos_timer_info *info) {
180
186
return true;
181
187
}
182
188
183
- static void mgos_time_change_cb ( int ev , void * evd , void * arg ) {
189
+ static void mgos_poll_cb ( void * arg ) {
184
190
struct timer_data * td = (struct timer_data * ) arg ;
185
- struct mgos_time_changed_arg * ev_data = (struct mgos_time_changed_arg * ) evd ;
186
191
mgos_rlock (s_timer_data_lock );
187
- struct timer_info * ti ;
188
- LIST_FOREACH (ti , & td -> timers , entries ) {
189
- ti -> next_invocation += ev_data -> delta ;
190
- }
192
+ schedule_next_timer (td , mgos_uptime ());
191
193
mgos_runlock (s_timer_data_lock );
194
+ }
192
195
196
+ static void mgos_time_change_cb (int ev , void * evd , void * arg ) {
197
+ mgos_poll_cb (arg );
198
+ (void ) evd ;
193
199
(void ) ev ;
194
200
}
195
201
@@ -207,5 +213,6 @@ enum mgos_init_result mgos_timers_init(void) {
207
213
s_timer_data = td ;
208
214
s_timer_data_lock = mgos_rlock_create ();
209
215
mgos_event_add_handler (MGOS_EVENT_TIME_CHANGED , mgos_time_change_cb , td );
216
+ mgos_add_poll_cb (mgos_poll_cb , td );
210
217
return mgos_hw_timers_init ();
211
218
}
0 commit comments