diff --git a/nfq2/darkmagic.c b/nfq2/darkmagic.c index cbf0751..21edb90 100644 --- a/nfq2/darkmagic.c +++ b/nfq2/darkmagic.c @@ -1643,7 +1643,7 @@ static bool windivert_recv_filter(HANDLE hFilter, uint8_t *packet, size_t *len, if (params.timers) { - if (!*bt_next) *bt_next = TimerPoolNext(params.timers, ¶ms.timers_dirty); + if (!*bt_next || params.timers_dirty) *bt_next = TimerPoolNext(params.timers, ¶ms.timers_dirty); bt = boottime_ms(); tmax = *bt_next>bt ? *bt_next-bt : 0; if (!tmax) diff --git a/nfq2/lua.c b/nfq2/lua.c index 3fe1845..b73baf7 100644 --- a/nfq2/lua.c +++ b/nfq2/lua.c @@ -3826,6 +3826,7 @@ static int luacall_timer_set(lua_State *L) if (timer) { TimerPoolDel(¶ms.timers, timer); + params.timers_dirty = true; action = "replaced"; } else @@ -3837,6 +3838,7 @@ static int luacall_timer_set(lua_State *L) lua_pop(L, 1); luaL_error(L,"could not create timer"); } + params.timers_dirty = true; timer->func_ref = luaL_ref(L, LUA_REGISTRYINDEX); if (argc>=5) @@ -3845,7 +3847,6 @@ static int luacall_timer_set(lua_State *L) timer->lua_ref = luaL_ref(L, LUA_REGISTRYINDEX); } DLOG("timer: '%s' %s. period %llu oneshot %u\n", timer->str, action, timer->period, timer->oneshot); - params.timers_dirty = true; LUA_STACK_GUARD_RETURN(L,0) } diff --git a/nfq2/timer.c b/nfq2/timer.c index 3f18ecc..fb2e209 100644 --- a/nfq2/timer.c +++ b/nfq2/timer.c @@ -103,44 +103,59 @@ again: { if (bt >= elem->bt_next) { - if (!(name = strdup(elem->str))) - return 0; - n = elem->n; - - del = NULL; - if (!TimerPoolRunTimer(elem)) - del = "timer: '%s' deleted because of error\n"; - - if (*dirty) + if (name = strdup(elem->str)) { - // timer function could delete the timer or recreate with the same name - p = TimerPoolSearch(*pp, name); - if (p!=elem || p->n!=n) elem = NULL; // timer deleted or recreated with the same name (but another 'n') - } - if (elem) - { - if (!del && elem->oneshot) - del = "timer: '%s' deleted because of oneshot\n"; - // elem is valid, not deleted and not recreated - if (del) + n = elem->n; + + del = NULL; + if (!TimerPoolRunTimer(elem)) + del = "timer: '%s' deleted because of error\n"; + + if (*dirty) { - DLOG(del,name); + // timer function could delete the timer or recreate with the same name + p = TimerPoolSearch(*pp, name); + if (p!=elem || p->n!=n) elem = NULL; // timer deleted or recreated with the same name (but another 'n') + } + if (elem) + { + if (!del && elem->oneshot) + del = "timer: '%s' deleted because of oneshot\n"; + // elem is valid, not deleted and not recreated + if (del) + { + DLOG(del,name); + TimerPoolDel(pp, elem); + elem = NULL; + } + else + { + // in case process was freezed (--ssid-filter/nlm-filter stop in winws for example) + // do not use previous activation time or timer can hit multiple times + // use current time instead to prevent bulk activation + elem->bt_next = bt + elem->period; + } + } + + free(name); + + if (*dirty) + goto again; // they may have deleted or created any number of timers, HASH_ITER may fail or access invalid pointers - restart + } + else // unlikely + { + if (elem->oneshot) + { + DLOG("timer: '%s' deleted because of out of memory\n", elem->str); TimerPoolDel(pp, elem); elem = NULL; } else { - // in case process was freezed (--ssid-filter/nlm-filter stop in winws for example) - // do not use previous activation time or timer can hit multiple times - // use current time instead to prevent bulk activation + DLOG("timer: '%s' skipped because of out of memory\n", elem->str); elem->bt_next = bt + elem->period; } } - - free(name); - - if (*dirty) - goto again; // they may have deleted or created any number of timers, HASH_ITER may fail or access invalid pointers - restart } if (elem && (elem->bt_next < mintime)) mintime = elem->bt_next; }