summaryrefslogtreecommitdiff
path: root/content/handlers/javascript/duktape/Window.bnd
diff options
context:
space:
mode:
Diffstat (limited to 'content/handlers/javascript/duktape/Window.bnd')
-rw-r--r--content/handlers/javascript/duktape/Window.bnd66
1 files changed, 56 insertions, 10 deletions
diff --git a/content/handlers/javascript/duktape/Window.bnd b/content/handlers/javascript/duktape/Window.bnd
index 478f92b99..a5ff2002d 100644
--- a/content/handlers/javascript/duktape/Window.bnd
+++ b/content/handlers/javascript/duktape/Window.bnd
@@ -12,13 +12,14 @@ class Window {
private struct browser_window * win;
private struct html_content * htmlc;
private struct window_schedule_s * schedule_ring;
+ private bool closed_down;
prologue %{
#include "utils/corestrings.h"
#include "utils/nsurl.h"
#include "netsurf/browser_window.h"
#include "content/hlcache.h"
#include "html/html.h"
-#include "html/html_internal.h"
+#include "html/private.h"
#include "desktop/gui_internal.h"
#include "netsurf/misc.h"
#include "utils/ring.h"
@@ -138,7 +139,7 @@ window_alloc_new_callback(duk_context *ctx,
int timeout)
{
size_t new_handle = next_handle++;
- window_schedule_t *sched = calloc(sizeof *sched, 1);
+ window_schedule_t *sched = calloc(1, sizeof *sched);
if (sched == NULL) {
return new_handle;
}
@@ -216,8 +217,8 @@ window_remove_callback_by_handle(duk_context *ctx,
} RING_ITERATE_END(window->schedule_ring, sched);
}
-/* This is the dodgy compartment closedown method */
-static duk_ret_t dukky_window_closedown_compartment(duk_context *ctx)
+/* This is the dodgy thread closedown method */
+static duk_ret_t dukky_window_closedown_thread(duk_context *ctx)
{
window_private_t *priv = NULL;
@@ -230,11 +231,42 @@ static duk_ret_t dukky_window_closedown_compartment(duk_context *ctx)
return 0;
}
- NSLOG(dukky, DEEPDEBUG, "Closing down compartment");
+ priv->closed_down = true;
+
+ 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;
@@ -245,10 +277,14 @@ static duk_ret_t dukky_window_closedown_compartment(duk_context *ctx)
init Window(struct browser_window *win, struct html_content *htmlc)
%{
+ /* It makes no sense if win or htmlc are NULL */
+ assert(win != NULL);
+ assert(htmlc != NULL);
/* element window */
priv->win = win;
priv->htmlc = htmlc;
priv->schedule_ring = NULL;
+ priv->closed_down = false;
NSLOG(netsurf, DEEPDEBUG, "win=%p htmlc=%p", priv->win, priv->htmlc);
NSLOG(netsurf, DEEPDEBUG,
@@ -273,7 +309,7 @@ prototype Window()
duk_put_prop_string(ctx, 0, #v)
/* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects */
/* ** Value properties */
- EXPOSE(infinity);
+ EXPOSE(Infinity);
EXPOSE(NaN);
EXPOSE(undefined);
EXPOSE(null);
@@ -361,10 +397,10 @@ prototype Window()
/* ** WebAssembly */
/* As yet, Duktape lacks WA */
#undef EXPOSE
- /* Add s3kr1t method to close the compartment */
+ /* Add s3kr1t method to close the JS thread (browsing context) */
duk_dup(ctx, 0);
- duk_push_string(ctx, MAGIC(closedownCompartment));
- duk_push_c_function(ctx, dukky_window_closedown_compartment, DUK_VARARGS);
+ duk_push_string(ctx, MAGIC(closedownThread));
+ duk_push_c_function(ctx, dukky_window_closedown_thread, DUK_VARARGS);
duk_def_prop(ctx, -3,
DUK_DEFPROP_HAVE_VALUE |
DUK_DEFPROP_HAVE_WRITABLE |
@@ -481,6 +517,11 @@ method Window::setTimeout()
%{
duk_idx_t argc = duk_get_top(ctx);
duk_int_t timeout = 10;
+
+ if (priv->closed_down == true) {
+ return 0; /* coerced to undefined */
+ }
+
if (argc >= 2) {
timeout = duk_get_int(ctx, 1);
}
@@ -496,6 +537,11 @@ method Window::setInterval()
%{
duk_idx_t argc = duk_get_top(ctx);
duk_int_t timeout = 10;
+
+ if (priv->closed_down == true) {
+ return 0; /* coerced to undefined */
+ }
+
if (argc >= 2) {
timeout = duk_get_int(ctx, 1);
}