Skip to content
Snippets Groups Projects
Commit 587663aa authored by deuce's avatar deuce
Browse files

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?).
parent 19efe3fe
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -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,15 +238,20 @@ 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)) {
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? */
if(cb->limit && cb->counter > cb->limit) {
......
......@@ -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))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment