Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/6a2ce2b3c74c3f5b0d0faee9fb0d6517bbc64fd7
...commit
http://git.netsurf-browser.org/netsurf.git/commit/6a2ce2b3c74c3f5b0d0faee9fb0d6517bbc64fd7
...tree
http://git.netsurf-browser.org/netsurf.git/tree/6a2ce2b3c74c3f5b0d0faee9fb0d6517bbc64fd7
The branch, master has been updated
via 6a2ce2b3c74c3f5b0d0faee9fb0d6517bbc64fd7 (commit)
via 8f7bfb7b564069ed5d2bb81a709f49724a795959 (commit)
via d1e2eef18b25e97c7c06068aa519003605202853 (commit)
via efbfaa0cb1808a3953f1595b9c5e1be9d7994469 (commit)
via 98e461a3b3580cfee2356459557d4f58b7db987c (commit)
from 80e7ac7345f084da1b909cd7dee32cf05aa5cb56 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=6a2ce2b3c74c3f5b0d0faee9fb0d6517bbc64fd7
commit 6a2ce2b3c74c3f5b0d0faee9fb0d6517bbc64fd7
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>
HTML: Use new js_closethread()
Signed-off-by: Daniel Silverstone <[email protected]>
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index 5b6a15f..871a5e8 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -1969,6 +1969,7 @@ html_open(struct content *c,
static nserror html_close(struct content *c)
{
html_content *htmlc = (html_content *) c;
+ nserror ret = NSERROR_OK;
selection_clear(&htmlc->sel, false);
@@ -1982,7 +1983,12 @@ static nserror html_close(struct content *c)
/* remove all object references from the html content */
html_object_close_objects(htmlc);
- return NSERROR_OK;
+ if (htmlc->jsthread != NULL) {
+ /* Close, but do not destroy (yet) the JS thread */
+ ret = js_closethread(htmlc->jsthread);
+ }
+
+ return ret;
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=8f7bfb7b564069ed5d2bb81a709f49724a795959
commit 8f7bfb7b564069ed5d2bb81a709f49724a795959
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>
Window: Add flag to ensure we don't set timeouts after close
Signed-off-by: Daniel Silverstone <[email protected]>
diff --git a/content/handlers/javascript/duktape/Window.bnd
b/content/handlers/javascript/duktape/Window.bnd
index b4a467d..d87c94f 100644
--- a/content/handlers/javascript/duktape/Window.bnd
+++ b/content/handlers/javascript/duktape/Window.bnd
@@ -12,6 +12,7 @@ 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"
@@ -230,6 +231,8 @@ static duk_ret_t dukky_window_closedown_thread(duk_context
*ctx)
return 0;
}
+ priv->closed_down = true;
+
NSLOG(dukky, DEEPDEBUG, "Closing down thread");
while (priv->schedule_ring != NULL) {
window_remove_callback_by_handle(ctx,
@@ -249,6 +252,7 @@ init Window(struct browser_window *win, struct html_content
*htmlc)
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,
@@ -481,6 +485,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 +505,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);
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=d1e2eef18b25e97c7c06068aa519003605202853
commit d1e2eef18b25e97c7c06068aa519003605202853
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>
JS: Add concept of js_closethread
In order to better model content close vs destroy, add the concept
of closing a thread to the JS interface.
Signed-off-by: Daniel Silverstone <[email protected]>
diff --git a/content/handlers/javascript/duktape/dukky.c
b/content/handlers/javascript/duktape/dukky.c
index bb227d4..7357863 100644
--- a/content/handlers/javascript/duktape/dukky.c
+++ b/content/handlers/javascript/duktape/dukky.c
@@ -754,6 +754,26 @@ nserror js_newthread(jsheap *heap, void *win_priv, void
*doc_priv, jsthread **th
#undef CTX
#define CTX (thread->ctx)
+/* exported interface documented in js.h */
+nserror js_closethread(jsthread *thread)
+{
+ /* We can always close down a thread, it might just confuse
+ * the code running, though we don't mind since we're in the
+ * process of destruction at this point
+ */
+ duk_int_t top = duk_get_top(CTX);
+
+ /* Closing down the extant thread */
+ NSLOG(dukky, DEBUG, "Closing down extant thread %p in heap %p", thread,
thread->heap);
+ duk_get_global_string(CTX, MAGIC(closedownThread));
+ dukky_pcall(CTX, 0, true);
+
+ /* Restore whatever stack we had */
+ duk_set_top(CTX, top);
+
+ return NSERROR_OK;
+}
+
/**
* Destroy a Duktape thread
*/
diff --git a/content/handlers/javascript/js.h b/content/handlers/javascript/js.h
index ce9bb9b..55f8e22 100644
--- a/content/handlers/javascript/js.h
+++ b/content/handlers/javascript/js.h
@@ -97,14 +97,27 @@ void js_destroyheap(jsheap *heap);
nserror js_newthread(jsheap *heap, void *win_priv, void *doc_priv, jsthread
**thread);
/**
+ * Close a javascript thread
+ *
+ * This should be called when the HTML content which owns the thread is
+ * being closed. This is a separate process from destroying the thread
+ * and merely disconnects any callbacks and thus hopefully stops
+ * additional JS things from triggering. If any code runs and attempts to
+ * register callbacks after closedown, they will fail.
+ *
+ * \param thread The thread to close down
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+nserror js_closethread(jsthread *thread);
+
+/**
* Destroy a javascript thread
*
* This should be called when the browsing context is done with the thread.
*
- * Essentially it should be called when the content is about to be destroyed
- * but in reality it can be called when the browser window relinquishes its
- * handle on the content since nominally the browser window itself owns
- * the thread.
+ * This will be called when the HTML content associated with the browsing
+ * context is being destroyed. The thread should have already been closed
+ * down during the HTML content close.
*
* \param thread The thread to be destroyed
*/
diff --git a/content/handlers/javascript/none/none.c
b/content/handlers/javascript/none/none.c
index ff09f52..ee01730 100644
--- a/content/handlers/javascript/none/none.c
+++ b/content/handlers/javascript/none/none.c
@@ -51,6 +51,11 @@ nserror js_newthread(jsheap *heap, void *win_priv, void
*doc_priv, jsthread **th
return NSERROR_NOT_IMPLEMENTED;
}
+nserror js_closethread(jsthread *thread)
+{
+ return NSERROR_OK;
+}
+
void js_destroythread(jsthread *thread)
{
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=efbfaa0cb1808a3953f1595b9c5e1be9d7994469
commit efbfaa0cb1808a3953f1595b9c5e1be9d7994469
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>
JS: Move ownership of jsthread from browser to htmlc
Since it makes more sense for the htmlc to be responsible for
when the JS thread gets destroyed, move its lifetime from the
responsibility of the browser window to the html content.
Signed-off-by: Daniel Silverstone <[email protected]>
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index 26be58d..5b6a15f 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -1637,12 +1637,6 @@ static void html_stop(struct content *c)
{
html_content *htmlc = (html_content *) c;
- /* invalidate the html content reference to the javascript context
- * as it is about to become invalid and must not be used any
- * more.
- */
- html_script_invalidate_ctx(htmlc);
-
switch (c->status) {
case CONTENT_STATUS_LOADING:
/* Still loading; simply flag that we've been aborted
@@ -1853,6 +1847,14 @@ static void html_destroy(struct content *c)
if (html->base_url)
nsurl_unref(html->base_url);
+ /* At this point we can be moderately confident the JS is offline
+ * so we destroy the JS thread.
+ */
+ if (html->jsthread != NULL) {
+ js_destroythread(html->jsthread);
+ html->jsthread = NULL;
+ }
+
if (html->parser != NULL) {
dom_hubbub_parser_destroy(html->parser);
html->parser = NULL;
@@ -1977,12 +1979,6 @@ static nserror html_close(struct content *c)
/* clear the html content reference to the browser window */
htmlc->bw = NULL;
- /* invalidate the html content reference to the javascript context
- * as it is about to become invalid and must not be used any
- * more.
- */
- html_script_invalidate_ctx(htmlc);
-
/* remove all object references from the html content */
html_object_close_objects(htmlc);
diff --git a/content/handlers/html/html_internal.h
b/content/handlers/html/html_internal.h
index a640781..7340bd2 100644
--- a/content/handlers/html/html_internal.h
+++ b/content/handlers/html/html_internal.h
@@ -321,14 +321,6 @@ nserror html_script_exec(html_content *htmlc, bool
allow_defer);
nserror html_script_free(html_content *htmlc);
/**
- * Ensure the html content javascript context is invalidated.
- *
- * \param htmlc html content.
- * \return NSERROR_OK or error code.
- */
-nserror html_script_invalidate_ctx(html_content *htmlc);
-
-/**
* Check if any of the scripts loaded were insecure
*/
bool html_saw_insecure_scripts(html_content *htmlc);
diff --git a/content/handlers/html/html_script.c
b/content/handlers/html/html_script.c
index 301acad..81bdccd 100644
--- a/content/handlers/html/html_script.c
+++ b/content/handlers/html/html_script.c
@@ -664,10 +664,3 @@ nserror html_script_free(html_content *html)
return NSERROR_OK;
}
-
-/* exported internal interface documented in html/html_internal.h */
-nserror html_script_invalidate_ctx(html_content *htmlc)
-{
- htmlc->jsthread = NULL;
- return NSERROR_OK;
-}
diff --git a/desktop/browser_private.h b/desktop/browser_private.h
index 89dc5cc..ed2d845 100644
--- a/desktop/browser_private.h
+++ b/desktop/browser_private.h
@@ -265,12 +265,6 @@ struct browser_window {
/** current javascript context */
struct jsheap *jsheap;
- /** The JS thread (if any) for the current content */
- struct jsthread *current_jsthread;
-
- /** The JS thread (if any) for the loading content */
- struct jsthread *loading_jsthread;
-
/** cache of the currently displayed status text. */
struct {
char *text; /**< Current status bar text. */
diff --git a/desktop/browser_window.c b/desktop/browser_window.c
index c98eca8..9151ee1 100644
--- a/desktop/browser_window.c
+++ b/desktop/browser_window.c
@@ -701,11 +701,6 @@ browser_window_convert_to_download(struct browser_window
*bw,
/* remove content from browser window */
hlcache_handle_release(bw->loading_content);
- bw->loading_content = NULL;
- if (bw->loading_jsthread != NULL) {
- js_destroythread(bw->loading_jsthread);
- bw->loading_jsthread = NULL;
- }
browser_window_stop_throbber(bw);
}
@@ -723,15 +718,10 @@ static nserror browser_window_content_ready(struct
browser_window *bw)
if (bw->current_content != NULL) {
content_close(bw->current_content);
hlcache_handle_release(bw->current_content);
- if (bw->current_jsthread != NULL) {
- js_destroythread(bw->current_jsthread);
- }
}
bw->current_content = bw->loading_content;
- bw->current_jsthread = bw->loading_jsthread;
bw->loading_content = NULL;
- bw->loading_jsthread = NULL;
if (!bw->internal_nav) {
/* Transfer the fetch parameters */
@@ -1289,10 +1279,6 @@ browser_window__handle_error(struct browser_window *bw,
if (c == bw->loading_content) {
bw->loading_content = NULL;
- if (bw->loading_jsthread != NULL) {
- js_destroythread(bw->loading_jsthread);
- bw->loading_jsthread = NULL;
- }
} else if (c == bw->current_content) {
bw->current_content = NULL;
browser_window_remove_caret(bw, false);
@@ -1499,16 +1485,23 @@ browser_window_callback(hlcache_handle *c, const
hlcache_event *event, void *pw)
break;
case CONTENT_MSG_GETTHREAD:
- /* only the content object created by the browser
- * window requires a new javascript thread object
- */
- assert(bw->loading_content == c);
- assert(bw->loading_jsthread == NULL);
- if (js_newthread(bw->jsheap,
- bw,
- hlcache_handle_get_content(c),
- &bw->loading_jsthread) == NSERROR_OK) {
- *(event->data.jsthread) = bw->loading_jsthread;
+ {
+ /* only the content object created by the browser
+ * window requires a new javascript thread object
+ */
+ jsthread *thread;
+ assert(bw->loading_content == c);
+
+ if (js_newthread(bw->jsheap,
+ bw,
+ hlcache_handle_get_content(c),
+ &thread) == NSERROR_OK) {
+ /* The content which is requesting the thread
+ * is required to keep hold of it and
+ * to destroy it when it is finished with it.
+ */
+ *(event->data.jsthread) = thread;
+ }
}
break;
@@ -1752,22 +1745,12 @@ static void browser_window_destroy_internal(struct
browser_window *bw)
bw->loading_content = NULL;
}
- if (bw->loading_jsthread != NULL) {
- js_destroythread(bw->loading_jsthread);
- bw->loading_jsthread = NULL;
- }
-
if (bw->current_content != NULL) {
content_close(bw->current_content);
hlcache_handle_release(bw->current_content);
bw->current_content = NULL;
}
- if (bw->current_jsthread != NULL) {
- js_destroythread(bw->current_jsthread);
- bw->current_jsthread = NULL;
- }
-
if (bw->favicon.loading != NULL) {
hlcache_handle_abort(bw->favicon.loading);
hlcache_handle_release(bw->favicon.loading);
@@ -4091,10 +4074,6 @@ void browser_window_stop(struct browser_window *bw)
hlcache_handle_abort(bw->loading_content);
hlcache_handle_release(bw->loading_content);
bw->loading_content = NULL;
- if (bw->loading_jsthread != NULL) {
- js_destroythread(bw->loading_jsthread);
- bw->loading_jsthread = NULL;
- }
}
if (bw->current_content != NULL &&
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=98e461a3b3580cfee2356459557d4f58b7db987c
commit 98e461a3b3580cfee2356459557d4f58b7db987c
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>
Dukky: Make heaps refcounted too
Signed-off-by: Daniel Silverstone <[email protected]>
diff --git a/content/handlers/javascript/duktape/dukky.c
b/content/handlers/javascript/duktape/dukky.c
index 862f0e4..bb227d4 100644
--- a/content/handlers/javascript/duktape/dukky.c
+++ b/content/handlers/javascript/duktape/dukky.c
@@ -59,6 +59,7 @@
struct jsheap {
duk_context *ctx; /**< duktape base context */
duk_uarridx_t next_thread; /**< monotonic thread counter */
+ bool pending_destroy; /**< Whether this heap is pending destruction */
unsigned int live_threads; /**< number of live threads */
uint64_t exec_start_time;
};
@@ -621,15 +622,24 @@ js_newheap(int timeout, jsheap **heap)
}
-/* exported interface documented in js.h */
-void js_destroyheap(jsheap *heap)
+static void dukky_destroyheap(jsheap *heap)
{
+ assert(heap->pending_destroy == true);
assert(heap->live_threads == 0);
NSLOG(dukky, DEBUG, "Destroying duktape javascript context");
duk_destroy_heap(heap->ctx);
free(heap);
}
+/* exported interface documented in js.h */
+void js_destroyheap(jsheap *heap)
+{
+ heap->pending_destroy = true;
+ if (heap->live_threads == 0) {
+ dukky_destroyheap(heap);
+ }
+}
+
/* Just for here, the CTX is in ret, not thread */
#define CTX (ret->ctx)
@@ -638,6 +648,7 @@ nserror js_newthread(jsheap *heap, void *win_priv, void
*doc_priv, jsthread **th
{
jsthread *ret;
assert(heap != NULL);
+ assert(heap->pending_destroy == false);
ret = calloc(1, sizeof (*ret));
if (ret == NULL) {
@@ -770,6 +781,11 @@ static void dukky_destroythread(jsthread *thread)
duk_gc(heap->ctx, 0);
duk_gc(heap->ctx, DUK_GC_COMPACT);
heap->live_threads--;
+
+ /* And if the heap should now go, blow it away */
+ if (heap->pending_destroy == true && heap->live_threads == 0) {
+ dukky_destroyheap(heap);
+ }
}
/* exported interface documented in js.h */
-----------------------------------------------------------------------
Summary of changes:
content/handlers/html/html.c | 28 ++++++------
content/handlers/html/html_internal.h | 8 ----
content/handlers/html/html_script.c | 7 ---
content/handlers/javascript/duktape/Window.bnd | 14 ++++++
content/handlers/javascript/duktape/dukky.c | 40 ++++++++++++++++-
content/handlers/javascript/js.h | 21 +++++++--
content/handlers/javascript/none/none.c | 5 +++
desktop/browser_private.h | 6 ---
desktop/browser_window.c | 55 ++++++++----------------
9 files changed, 106 insertions(+), 78 deletions(-)
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index 26be58d..871a5e8 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -1637,12 +1637,6 @@ static void html_stop(struct content *c)
{
html_content *htmlc = (html_content *) c;
- /* invalidate the html content reference to the javascript context
- * as it is about to become invalid and must not be used any
- * more.
- */
- html_script_invalidate_ctx(htmlc);
-
switch (c->status) {
case CONTENT_STATUS_LOADING:
/* Still loading; simply flag that we've been aborted
@@ -1853,6 +1847,14 @@ static void html_destroy(struct content *c)
if (html->base_url)
nsurl_unref(html->base_url);
+ /* At this point we can be moderately confident the JS is offline
+ * so we destroy the JS thread.
+ */
+ if (html->jsthread != NULL) {
+ js_destroythread(html->jsthread);
+ html->jsthread = NULL;
+ }
+
if (html->parser != NULL) {
dom_hubbub_parser_destroy(html->parser);
html->parser = NULL;
@@ -1967,6 +1969,7 @@ html_open(struct content *c,
static nserror html_close(struct content *c)
{
html_content *htmlc = (html_content *) c;
+ nserror ret = NSERROR_OK;
selection_clear(&htmlc->sel, false);
@@ -1977,16 +1980,15 @@ static nserror html_close(struct content *c)
/* clear the html content reference to the browser window */
htmlc->bw = NULL;
- /* invalidate the html content reference to the javascript context
- * as it is about to become invalid and must not be used any
- * more.
- */
- html_script_invalidate_ctx(htmlc);
-
/* remove all object references from the html content */
html_object_close_objects(htmlc);
- return NSERROR_OK;
+ if (htmlc->jsthread != NULL) {
+ /* Close, but do not destroy (yet) the JS thread */
+ ret = js_closethread(htmlc->jsthread);
+ }
+
+ return ret;
}
diff --git a/content/handlers/html/html_internal.h
b/content/handlers/html/html_internal.h
index a640781..7340bd2 100644
--- a/content/handlers/html/html_internal.h
+++ b/content/handlers/html/html_internal.h
@@ -321,14 +321,6 @@ nserror html_script_exec(html_content *htmlc, bool
allow_defer);
nserror html_script_free(html_content *htmlc);
/**
- * Ensure the html content javascript context is invalidated.
- *
- * \param htmlc html content.
- * \return NSERROR_OK or error code.
- */
-nserror html_script_invalidate_ctx(html_content *htmlc);
-
-/**
* Check if any of the scripts loaded were insecure
*/
bool html_saw_insecure_scripts(html_content *htmlc);
diff --git a/content/handlers/html/html_script.c
b/content/handlers/html/html_script.c
index 301acad..81bdccd 100644
--- a/content/handlers/html/html_script.c
+++ b/content/handlers/html/html_script.c
@@ -664,10 +664,3 @@ nserror html_script_free(html_content *html)
return NSERROR_OK;
}
-
-/* exported internal interface documented in html/html_internal.h */
-nserror html_script_invalidate_ctx(html_content *htmlc)
-{
- htmlc->jsthread = NULL;
- return NSERROR_OK;
-}
diff --git a/content/handlers/javascript/duktape/Window.bnd
b/content/handlers/javascript/duktape/Window.bnd
index b4a467d..d87c94f 100644
--- a/content/handlers/javascript/duktape/Window.bnd
+++ b/content/handlers/javascript/duktape/Window.bnd
@@ -12,6 +12,7 @@ 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"
@@ -230,6 +231,8 @@ static duk_ret_t dukky_window_closedown_thread(duk_context
*ctx)
return 0;
}
+ priv->closed_down = true;
+
NSLOG(dukky, DEEPDEBUG, "Closing down thread");
while (priv->schedule_ring != NULL) {
window_remove_callback_by_handle(ctx,
@@ -249,6 +252,7 @@ init Window(struct browser_window *win, struct html_content
*htmlc)
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,
@@ -481,6 +485,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 +505,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);
}
diff --git a/content/handlers/javascript/duktape/dukky.c
b/content/handlers/javascript/duktape/dukky.c
index 862f0e4..7357863 100644
--- a/content/handlers/javascript/duktape/dukky.c
+++ b/content/handlers/javascript/duktape/dukky.c
@@ -59,6 +59,7 @@
struct jsheap {
duk_context *ctx; /**< duktape base context */
duk_uarridx_t next_thread; /**< monotonic thread counter */
+ bool pending_destroy; /**< Whether this heap is pending destruction */
unsigned int live_threads; /**< number of live threads */
uint64_t exec_start_time;
};
@@ -621,15 +622,24 @@ js_newheap(int timeout, jsheap **heap)
}
-/* exported interface documented in js.h */
-void js_destroyheap(jsheap *heap)
+static void dukky_destroyheap(jsheap *heap)
{
+ assert(heap->pending_destroy == true);
assert(heap->live_threads == 0);
NSLOG(dukky, DEBUG, "Destroying duktape javascript context");
duk_destroy_heap(heap->ctx);
free(heap);
}
+/* exported interface documented in js.h */
+void js_destroyheap(jsheap *heap)
+{
+ heap->pending_destroy = true;
+ if (heap->live_threads == 0) {
+ dukky_destroyheap(heap);
+ }
+}
+
/* Just for here, the CTX is in ret, not thread */
#define CTX (ret->ctx)
@@ -638,6 +648,7 @@ nserror js_newthread(jsheap *heap, void *win_priv, void
*doc_priv, jsthread **th
{
jsthread *ret;
assert(heap != NULL);
+ assert(heap->pending_destroy == false);
ret = calloc(1, sizeof (*ret));
if (ret == NULL) {
@@ -743,6 +754,26 @@ nserror js_newthread(jsheap *heap, void *win_priv, void
*doc_priv, jsthread **th
#undef CTX
#define CTX (thread->ctx)
+/* exported interface documented in js.h */
+nserror js_closethread(jsthread *thread)
+{
+ /* We can always close down a thread, it might just confuse
+ * the code running, though we don't mind since we're in the
+ * process of destruction at this point
+ */
+ duk_int_t top = duk_get_top(CTX);
+
+ /* Closing down the extant thread */
+ NSLOG(dukky, DEBUG, "Closing down extant thread %p in heap %p", thread,
thread->heap);
+ duk_get_global_string(CTX, MAGIC(closedownThread));
+ dukky_pcall(CTX, 0, true);
+
+ /* Restore whatever stack we had */
+ duk_set_top(CTX, top);
+
+ return NSERROR_OK;
+}
+
/**
* Destroy a Duktape thread
*/
@@ -770,6 +801,11 @@ static void dukky_destroythread(jsthread *thread)
duk_gc(heap->ctx, 0);
duk_gc(heap->ctx, DUK_GC_COMPACT);
heap->live_threads--;
+
+ /* And if the heap should now go, blow it away */
+ if (heap->pending_destroy == true && heap->live_threads == 0) {
+ dukky_destroyheap(heap);
+ }
}
/* exported interface documented in js.h */
diff --git a/content/handlers/javascript/js.h b/content/handlers/javascript/js.h
index ce9bb9b..55f8e22 100644
--- a/content/handlers/javascript/js.h
+++ b/content/handlers/javascript/js.h
@@ -97,14 +97,27 @@ void js_destroyheap(jsheap *heap);
nserror js_newthread(jsheap *heap, void *win_priv, void *doc_priv, jsthread
**thread);
/**
+ * Close a javascript thread
+ *
+ * This should be called when the HTML content which owns the thread is
+ * being closed. This is a separate process from destroying the thread
+ * and merely disconnects any callbacks and thus hopefully stops
+ * additional JS things from triggering. If any code runs and attempts to
+ * register callbacks after closedown, they will fail.
+ *
+ * \param thread The thread to close down
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+nserror js_closethread(jsthread *thread);
+
+/**
* Destroy a javascript thread
*
* This should be called when the browsing context is done with the thread.
*
- * Essentially it should be called when the content is about to be destroyed
- * but in reality it can be called when the browser window relinquishes its
- * handle on the content since nominally the browser window itself owns
- * the thread.
+ * This will be called when the HTML content associated with the browsing
+ * context is being destroyed. The thread should have already been closed
+ * down during the HTML content close.
*
* \param thread The thread to be destroyed
*/
diff --git a/content/handlers/javascript/none/none.c
b/content/handlers/javascript/none/none.c
index ff09f52..ee01730 100644
--- a/content/handlers/javascript/none/none.c
+++ b/content/handlers/javascript/none/none.c
@@ -51,6 +51,11 @@ nserror js_newthread(jsheap *heap, void *win_priv, void
*doc_priv, jsthread **th
return NSERROR_NOT_IMPLEMENTED;
}
+nserror js_closethread(jsthread *thread)
+{
+ return NSERROR_OK;
+}
+
void js_destroythread(jsthread *thread)
{
}
diff --git a/desktop/browser_private.h b/desktop/browser_private.h
index 89dc5cc..ed2d845 100644
--- a/desktop/browser_private.h
+++ b/desktop/browser_private.h
@@ -265,12 +265,6 @@ struct browser_window {
/** current javascript context */
struct jsheap *jsheap;
- /** The JS thread (if any) for the current content */
- struct jsthread *current_jsthread;
-
- /** The JS thread (if any) for the loading content */
- struct jsthread *loading_jsthread;
-
/** cache of the currently displayed status text. */
struct {
char *text; /**< Current status bar text. */
diff --git a/desktop/browser_window.c b/desktop/browser_window.c
index c98eca8..9151ee1 100644
--- a/desktop/browser_window.c
+++ b/desktop/browser_window.c
@@ -701,11 +701,6 @@ browser_window_convert_to_download(struct browser_window
*bw,
/* remove content from browser window */
hlcache_handle_release(bw->loading_content);
- bw->loading_content = NULL;
- if (bw->loading_jsthread != NULL) {
- js_destroythread(bw->loading_jsthread);
- bw->loading_jsthread = NULL;
- }
browser_window_stop_throbber(bw);
}
@@ -723,15 +718,10 @@ static nserror browser_window_content_ready(struct
browser_window *bw)
if (bw->current_content != NULL) {
content_close(bw->current_content);
hlcache_handle_release(bw->current_content);
- if (bw->current_jsthread != NULL) {
- js_destroythread(bw->current_jsthread);
- }
}
bw->current_content = bw->loading_content;
- bw->current_jsthread = bw->loading_jsthread;
bw->loading_content = NULL;
- bw->loading_jsthread = NULL;
if (!bw->internal_nav) {
/* Transfer the fetch parameters */
@@ -1289,10 +1279,6 @@ browser_window__handle_error(struct browser_window *bw,
if (c == bw->loading_content) {
bw->loading_content = NULL;
- if (bw->loading_jsthread != NULL) {
- js_destroythread(bw->loading_jsthread);
- bw->loading_jsthread = NULL;
- }
} else if (c == bw->current_content) {
bw->current_content = NULL;
browser_window_remove_caret(bw, false);
@@ -1499,16 +1485,23 @@ browser_window_callback(hlcache_handle *c, const
hlcache_event *event, void *pw)
break;
case CONTENT_MSG_GETTHREAD:
- /* only the content object created by the browser
- * window requires a new javascript thread object
- */
- assert(bw->loading_content == c);
- assert(bw->loading_jsthread == NULL);
- if (js_newthread(bw->jsheap,
- bw,
- hlcache_handle_get_content(c),
- &bw->loading_jsthread) == NSERROR_OK) {
- *(event->data.jsthread) = bw->loading_jsthread;
+ {
+ /* only the content object created by the browser
+ * window requires a new javascript thread object
+ */
+ jsthread *thread;
+ assert(bw->loading_content == c);
+
+ if (js_newthread(bw->jsheap,
+ bw,
+ hlcache_handle_get_content(c),
+ &thread) == NSERROR_OK) {
+ /* The content which is requesting the thread
+ * is required to keep hold of it and
+ * to destroy it when it is finished with it.
+ */
+ *(event->data.jsthread) = thread;
+ }
}
break;
@@ -1752,22 +1745,12 @@ static void browser_window_destroy_internal(struct
browser_window *bw)
bw->loading_content = NULL;
}
- if (bw->loading_jsthread != NULL) {
- js_destroythread(bw->loading_jsthread);
- bw->loading_jsthread = NULL;
- }
-
if (bw->current_content != NULL) {
content_close(bw->current_content);
hlcache_handle_release(bw->current_content);
bw->current_content = NULL;
}
- if (bw->current_jsthread != NULL) {
- js_destroythread(bw->current_jsthread);
- bw->current_jsthread = NULL;
- }
-
if (bw->favicon.loading != NULL) {
hlcache_handle_abort(bw->favicon.loading);
hlcache_handle_release(bw->favicon.loading);
@@ -4091,10 +4074,6 @@ void browser_window_stop(struct browser_window *bw)
hlcache_handle_abort(bw->loading_content);
hlcache_handle_release(bw->loading_content);
bw->loading_content = NULL;
- if (bw->loading_jsthread != NULL) {
- js_destroythread(bw->loading_jsthread);
- bw->loading_jsthread = NULL;
- }
}
if (bw->current_content != NULL &&
--
NetSurf Browser
_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org