diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2019-06-09 11:04:15 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2019-06-09 11:04:15 +0100 |
commit | 04cf2fe588987e58bb17e83b2a2c39f73a6bd23c (patch) | |
tree | 4e15609c7b145b40d557d8a7f62432a47fde1eb0 /content | |
parent | dddc5eac944746b766ac1009d2b7063cabab0d3d (diff) | |
download | netsurf-04cf2fe588987e58bb17e83b2a2c39f73a6bd23c.tar.gz netsurf-04cf2fe588987e58bb17e83b2a2c39f73a6bd23c.tar.bz2 |
Window.bnd: Do not remove in-train callbacks
Sometimes callbacks may be cancelled from within themselves. In
that case we need to simply ensure that should the callback be
wanted to repeat, we instead stop that so that once the callback
is completed we do not attempt to reschedule something which had
already been deleted.
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'content')
-rw-r--r-- | content/handlers/javascript/duktape/Window.bnd | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/content/handlers/javascript/duktape/Window.bnd b/content/handlers/javascript/duktape/Window.bnd index 99615c207..731b2a335 100644 --- a/content/handlers/javascript/duktape/Window.bnd +++ b/content/handlers/javascript/duktape/Window.bnd @@ -36,6 +36,7 @@ typedef struct window_schedule_s { struct window_schedule_s *r_prev; size_t handle; int repeat_timeout; + bool running; } window_schedule_t; static void window_remove_callback_bits(duk_context *ctx, size_t handle) { @@ -100,7 +101,9 @@ static void window_schedule_callback(void *p) { NSLOG(dukky, DEEPDEBUG, "Entered window scheduler callback: %"PRIsizet, priv->handle); + priv->running = true; window_call_callback(priv->ctx, priv->handle, priv->repeat_timeout == 0); + priv->running = false; if (priv->repeat_timeout > 0) { /* Reschedule */ @@ -126,6 +129,7 @@ static size_t window_alloc_new_callback(duk_context *ctx, window_private_t *wind sched->ctx = ctx; sched->handle = new_handle; sched->repeat_timeout = repeating ? timeout : 0; + sched->running = false; RING_INSERT(window->schedule_ring, sched); @@ -171,14 +175,19 @@ static void window_remove_callback_by_handle(duk_context *ctx, RING_ITERATE_START(window_schedule_t, window->schedule_ring, sched) { if (sched->handle == handle) { - NSLOG(dukky, DEEPDEBUG, "Cancelled callback %"PRIsizet, sched->handle); - res = guit->misc->schedule(-1, - window_schedule_callback, - sched); - assert(res == NSERROR_OK); - RING_REMOVE(window->schedule_ring, sched); - window_remove_callback_bits(ctx, sched->handle); - free(sched); + if (sched->running) { + NSLOG(dukky, DEEPDEBUG, "Cancelling in-train callback %"PRIsizet, sched->handle); + sched->repeat_timeout = 0; + } else { + NSLOG(dukky, DEEPDEBUG, "Cancelled callback %"PRIsizet, sched->handle); + res = guit->misc->schedule(-1, + window_schedule_callback, + sched); + assert(res == NSERROR_OK); + RING_REMOVE(window->schedule_ring, sched); + window_remove_callback_bits(ctx, sched->handle); + free(sched); + } RING_ITERATE_STOP(window->schedule_ring, sched); } } RING_ITERATE_END(window->schedule_ring, sched); |