From 587663aae9166dc407e70df8879db89dca9776c5 Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sat, 26 Sep 2015 05:06:38 +0000 Subject: [PATCH] Store the parent js_callback_t in js_callback_t for background threads. When checking the terminated value, check all parents until you either find one that is TRUE, or run out of parents. Do *not* go up the chain of parents when *setting* terminated. Background threads still can't set it (TODO?). --- src/sbbs3/js_global.c | 14 ++++++++++++++ src/sbbs3/js_internal.c | 26 +++++++++++++++++++------- src/sbbs3/sbbsdefs.h | 5 ++++- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c index ca455b0e0c..c7287a9df5 100644 --- a/src/sbbs3/js_global.c +++ b/src/sbbs3/js_global.c @@ -255,6 +255,7 @@ js_load(JSContext *cx, uintN argc, jsval *arglist) jsval val; JSObject* js_argv; JSObject* exec_obj; + JSObject* js_internal; JSContext* exec_cx=cx; JSBool success; JSBool background=JS_FALSE; @@ -291,6 +292,19 @@ js_load(JSContext *cx, uintN argc, jsval *arglist) bg->cb.terminated=NULL; /* could be bad pointer at any time */ bg->cb.counter=0; bg->cb.gc_attempts=0; + bg->cb.bg = TRUE; + + // Get the js.internal private data since it's the parents js_callback_t... + if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "js", &val) && !JSVAL_NULL_OR_VOID(val)) { + js_internal = JSVAL_TO_OBJECT(val); + bg->cb.parent_cb = (js_callback_t*)JS_GetPrivate(cx,js_internal); + if (bg->cb.parent_cb == NULL) { + lprintf(LOG_ERR, "!ERROR parent CB is NULL"); + } + } + else { + lprintf(LOG_ERR, "!ERROR unabled to locate global js object"); + } if((bg->runtime = jsrt_GetNew(JAVASCRIPT_MAX_BYTES, 1000, __FILE__, __LINE__))==NULL) { free(bg); diff --git a/src/sbbs3/js_internal.c b/src/sbbs3/js_internal.c index e890d3c53f..6ca4bda482 100644 --- a/src/sbbs3/js_internal.c +++ b/src/sbbs3/js_internal.c @@ -64,6 +64,7 @@ static JSBool js_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) jsval idval; jsint tiny; js_callback_t* cb; + js_callback_t* top_cb; if((cb=(js_callback_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -76,10 +77,16 @@ static JSBool js_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) *vp=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,(char *)JS_GetImplementationVersion())); break; case PROP_TERMINATED: - if(cb->terminated==NULL) + for(top_cb=cb; top_cb->bg && top_cb->parent_cb; top_cb=top_cb->parent_cb) { + if(top_cb->terminated && *top_cb->terminated) { + *vp=BOOLEAN_TO_JSVAL(TRUE); + return JS_TRUE; + } + } + if(top_cb->terminated==NULL) *vp=JSVAL_FALSE; else - *vp=BOOLEAN_TO_JSVAL(*cb->terminated); + *vp=BOOLEAN_TO_JSVAL(*top_cb->terminated); break; case PROP_AUTO_TERMINATE: *vp=BOOLEAN_TO_JSVAL(cb->auto_terminate); @@ -231,14 +238,19 @@ static char* prop_desc[] = { JSBool DLLCALL js_CommonOperationCallback(JSContext *cx, js_callback_t* cb) { + js_callback_t *top_cb; + cb->counter++; /* Terminated? */ - if(cb->auto_terminate && - (cb->terminated!=NULL && *cb->terminated)) { - JS_ReportWarning(cx,"Terminated"); - cb->counter=0; - return(JS_FALSE); + if(cb->auto_terminate) { + for(top_cb=cb; top_cb; top_cb=top_cb->parent_cb) { + if (top_cb->terminated!=NULL && *top_cb->terminated) { + JS_ReportWarning(cx,"Terminated"); + cb->counter=0; + return(JS_FALSE); + } + } } /* Infinite loop? */ diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index dd8ae213e6..f19bba70b8 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -78,7 +78,8 @@ #define JAVASCRIPT_LOAD_PATH "load" #define JAVASCRIPT_LOAD_PATH_LIST "load_path_list" -typedef struct { +struct js_callback; +typedef struct js_callback { uint32_t counter; uint32_t limit; uint32_t yield_interval; @@ -86,6 +87,8 @@ typedef struct { uint32_t gc_attempts; BOOL auto_terminate; volatile BOOL* terminated; + BOOL bg; + struct js_callback *parent_cb; } js_callback_t; #define JSVAL_NULL_OR_VOID(val) (JSVAL_IS_NULL(val) || JSVAL_IS_VOID(val)) -- GitLab