Window: Do not get stuck if callbacks are in-train during compartment close

When we close the JS compartment we try and cancel all callbacks so that
they do not fire after the compartment is closed.  However if we have
in-train callbacks, they can gum up the closedown and so we need to check
and if we've done all we can, we break out of the callback removal loop.

Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
This commit is contained in:
Daniel Silverstone 2020-04-25 14:02:30 +01:00
parent bf4cbc95b0
commit 24ec30359b
No known key found for this signature in database
GPG Key ID: C30DF439F2987D74

View File

@ -235,9 +235,38 @@ static duk_ret_t dukky_window_closedown_thread(duk_context *ctx)
NSLOG(dukky, DEEPDEBUG, "Closing down thread");
while (priv->schedule_ring != NULL) {
window_schedule_t *to_remove = NULL;
// Find a schedule item to remove
RING_ITERATE_START(window_schedule_t, priv->schedule_ring, sched) {
if (sched->running == false) {
// This one is not running, we can remove it
to_remove = sched;
RING_ITERATE_STOP(window->schedule_ring, sched);
} else if (sched->repeat_timeout != 0) {
// This one is running and has yet to be
// cancelled, so prevent it rescheduling itself
NSLOG(dukky, DEEPDEBUG,
"Cancelling in-train callback %"PRIsizet,
sched->handle);
sched->repeat_timeout = 0;
}
} RING_ITERATE_END(priv->schedule_ring, sched);
if (to_remove == NULL) {
// We didn't find any non-running callbacks
// so let's log that and break out of the closedown
// loop so we can continue and hopefully close down
NSLOG(dukky, DEEPDEBUG,
"Leaving in-train callbacks to unwind");
break;
}
// Remove the handle we found, this will reduce the callback
// scheduler ring by one and perhaps leave it empty so we can
// finish the closedown.
window_remove_callback_by_handle(ctx,
priv,
priv->schedule_ring->handle);
to_remove->handle);
}
return 0;