From dddc5eac944746b766ac1009d2b7063cabab0d3d Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sat, 8 Jun 2019 13:33:16 +0100 Subject: Update schedulers return codes The GTK and monkey frontends schedulers now return NSERROR_NOT_FOUND when a caller is using a negative schedule time to remove a callback. --- content/handlers/javascript/duktape/Window.bnd | 7 +++- frontends/gtk/schedule.c | 52 +++++++++++++++++--------- frontends/monkey/schedule.c | 10 ++++- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/content/handlers/javascript/duktape/Window.bnd b/content/handlers/javascript/duktape/Window.bnd index 865d07421..99615c207 100644 --- a/content/handlers/javascript/duktape/Window.bnd +++ b/content/handlers/javascript/duktape/Window.bnd @@ -167,10 +167,15 @@ static size_t window_alloc_new_callback(duk_context *ctx, window_private_t *wind static void window_remove_callback_by_handle(duk_context *ctx, window_private_t *window, size_t handle) { + int res; + RING_ITERATE_START(window_schedule_t, window->schedule_ring, sched) { if (sched->handle == handle) { NSLOG(dukky, DEEPDEBUG, "Cancelled callback %"PRIsizet, sched->handle); - guit->misc->schedule(-1, window_schedule_callback, sched); + 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); diff --git a/frontends/gtk/schedule.c b/frontends/gtk/schedule.c index d5b45674b..69678924d 100644 --- a/frontends/gtk/schedule.c +++ b/frontends/gtk/schedule.c @@ -28,9 +28,9 @@ /** Killable callback closure embodiment. */ typedef struct { - void (*callback)(void *); /**< The callback function. */ - void *context; /**< The context for the callback. */ - bool callback_killed; /**< Whether or not this was killed. */ + void (*callback)(void *); /**< The callback function. */ + void *context; /**< The context for the callback. */ + bool callback_killed; /**< Whether or not this was killed. */ } _nsgtk_callback_t; /** List of callbacks which have occurred and are pending running. */ @@ -61,20 +61,29 @@ nsgtk_schedule_kill_callback(void *_target, void *_match) if ((target->callback == match->callback) && (target->context == match->context)) { NSLOG(schedule, DEBUG, - "Found match for %p(%p), killing.", + "Found match for %p(%p), killing.", target->callback, target->context); target->callback = NULL; target->context = NULL; target->callback_killed = true; + match->callback_killed = true; } } -static void -schedule_remove(void (*callback)(void *p), void *p) +/** + * remove a matching callback and context tuple from all lists + * + * \param callback The callback to match + * \param cbctx The callback context to match + * \return NSERROR_OK if the tuple was removed from at least one list else NSERROR_NOT_FOUND + */ +static nserror +schedule_remove(void (*callback)(void *p), void *cbctx) { _nsgtk_callback_t cb_match = { .callback = callback, - .context = p, + .context = cbctx, + .callback_killed = false, }; g_list_foreach(queued_callbacks, @@ -83,29 +92,36 @@ schedule_remove(void (*callback)(void *p), void *p) nsgtk_schedule_kill_callback, &cb_match); g_list_foreach(this_run, nsgtk_schedule_kill_callback, &cb_match); + + if (cb_match.callback_killed == false) { + return NSERROR_NOT_FOUND; + } + return NSERROR_OK; } /* exported interface documented in gtk/schedule.h */ -nserror nsgtk_schedule(int t, void (*callback)(void *p), void *p) +nserror nsgtk_schedule(int t, void (*callback)(void *p), void *cbctx) { - _nsgtk_callback_t *cb; + _nsgtk_callback_t *cb; + nserror res; /* Kill any pending schedule of this kind. */ - schedule_remove(callback, p); + res = schedule_remove(callback, cbctx); - if (t < 0) { - return NSERROR_OK; - } + /* only removal */ + if (t < 0) { + return res; + } - cb = malloc(sizeof(_nsgtk_callback_t)); + cb = malloc(sizeof(_nsgtk_callback_t)); cb->callback = callback; - cb->context = p; + cb->context = cbctx; cb->callback_killed = false; /* Prepend is faster right now. */ queued_callbacks = g_list_prepend(queued_callbacks, cb); g_timeout_add(t, nsgtk_schedule_generic_callback, cb); - return NSERROR_OK; + return NSERROR_OK; } bool @@ -121,7 +137,7 @@ schedule_run(void) pending_callbacks = NULL; NSLOG(schedule, DEBUG, - "Captured a run of %d callbacks to fire.", + "Captured a run of %d callbacks to fire.", g_list_length(this_run)); /* Run all the callbacks which made it this far. */ @@ -132,5 +148,5 @@ schedule_run(void) cb->callback(cb->context); free(cb); } - return true; + return true; } diff --git a/frontends/monkey/schedule.c b/frontends/monkey/schedule.c index 3d76997f4..9d3ab7af8 100644 --- a/frontends/monkey/schedule.c +++ b/frontends/monkey/schedule.c @@ -43,6 +43,7 @@ struct nscallback * * \param callback callback function * \param p user parameter, passed to callback function + * \return NSERROR_OK if callback found and removed else NSERROR_NOT_FOUND * * All scheduled callbacks matching both callback and p are removed. */ @@ -51,10 +52,11 @@ static nserror schedule_remove(void (*callback)(void *p), void *p) struct nscallback *cur_nscb; struct nscallback *prev_nscb; struct nscallback *unlnk_nscb; + bool removed = false; /* check there is something on the list to remove */ if (schedule_list == NULL) { - return NSERROR_OK; + return NSERROR_NOT_FOUND; } NSLOG(schedule, DEBUG, "removing %p, %p", callback, p); @@ -80,6 +82,7 @@ static nserror schedule_remove(void (*callback)(void *p), void *p) prev_nscb->next = cur_nscb; } free (unlnk_nscb); + removed = true; } else { /* move to next element */ prev_nscb = cur_nscb; @@ -87,6 +90,9 @@ static nserror schedule_remove(void (*callback)(void *p), void *p) } } + if (removed == false) { + return NSERROR_NOT_FOUND; + } return NSERROR_OK; } @@ -99,7 +105,7 @@ nserror monkey_schedule(int tival, void (*callback)(void *p), void *p) /* ensure uniqueness of the callback and context */ ret = schedule_remove(callback, p); - if ((tival < 0) || (ret != NSERROR_OK)) { + if (tival < 0) { return ret; } -- cgit v1.2.3