--- sbbs/src/sbbs3/js_queue.c 2018/04/24 16:41:23 1.1 +++ sbbs/src/sbbs3/js_queue.c 2018/04/24 16:42:38 1.1.1.2 @@ -2,13 +2,13 @@ /* Synchronet JavaScript "Queue" Object */ -/* $Id: js_queue.c,v 1.1 2018/04/24 16:41:23 root Exp $ */ +/* $Id: js_queue.c,v 1.1.1.2 2018/04/24 16:42:38 root Exp $ */ /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -37,6 +37,7 @@ #include "sbbs.h" #include "msg_queue.h" +#include "js_request.h" typedef struct { @@ -62,7 +63,7 @@ static void js_finalize_queue(JSContext if((q=(msg_queue_t*)JS_GetPrivate(cx,obj))==NULL) return; - + if(msgQueueDetach(q)==0 && (n=listFindNode(&named_queues,q,/* length=0 for ptr compare */0))!=NULL) listRemoveNode(&named_queues,n,FALSE); @@ -129,6 +130,7 @@ js_poll(JSContext *cx, JSObject *obj, ui msg_queue_t* q; queued_value_t* v; int32 timeout=0; + jsrefcount rc; if((q=(msg_queue_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -138,7 +140,10 @@ js_poll(JSContext *cx, JSObject *obj, ui if(argc && JSVAL_IS_NUMBER(argv[0])) /* timeout specified */ JS_ValueToInt32(cx,argv[0],&timeout); - if((v=msgQueuePeek(q,timeout))==NULL) + rc=JS_SUSPENDREQUEST(cx); + v=msgQueuePeek(q,timeout); + JS_RESUMEREQUEST(cx, rc); + if(v==NULL) *rval = JSVAL_FALSE; else if(v->name!=NULL && v->name[0]) *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,v->name)); @@ -155,6 +160,7 @@ js_read(JSContext *cx, JSObject *obj, ui queued_value_t find_v; queued_value_t* v; int32 timeout=0; + jsrefcount rc; if((q=(msg_queue_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -164,11 +170,15 @@ js_read(JSContext *cx, JSObject *obj, ui if(JSVAL_IS_STRING(argv[0])) { /* value named specified */ ZERO_VAR(find_v); SAFECOPY(find_v.name,JS_GetStringBytes(JS_ValueToString(cx,argv[0]))); + rc=JS_SUSPENDREQUEST(cx); v=msgQueueFind(q,&find_v,sizeof(find_v.name)); + JS_RESUMEREQUEST(cx, rc); } else { if(JSVAL_IS_NUMBER(argv[0])) JS_ValueToInt32(cx,argv[0],&timeout); + rc=JS_SUSPENDREQUEST(cx); v=msgQueueRead(q, timeout); + JS_RESUMEREQUEST(cx, rc); } if(v!=NULL) { @@ -185,6 +195,7 @@ js_peek(JSContext *cx, JSObject *obj, ui msg_queue_t* q; queued_value_t* v; int32 timeout=0; + jsrefcount rc; if((q=(msg_queue_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -194,7 +205,10 @@ js_peek(JSContext *cx, JSObject *obj, ui if(argc && JSVAL_IS_NUMBER(argv[0])) /* timeout specified */ JS_ValueToInt32(cx,argv[0],&timeout); - if((v=msgQueuePeek(q, timeout))!=NULL) { + rc=JS_SUSPENDREQUEST(cx); + v=msgQueuePeek(q, timeout); + JS_RESUMEREQUEST(cx, rc); + if(v!=NULL) { js_decode_value(cx, obj, v, rval, /* peek */TRUE); } @@ -281,12 +295,15 @@ BOOL js_enqueue_value(JSContext *cx, msg queued_value_t* v; size_t count=0; BOOL result; + jsrefcount rc; if((v=js_encode_value(cx,val,name,NULL,&count))==NULL || count<1) return(FALSE); + rc=JS_SUSPENDREQUEST(cx); result=msgQueueWrite(q,v,count*sizeof(queued_value_t)); free(v); + JS_RESUMEREQUEST(cx, rc); return(result); } @@ -335,6 +352,7 @@ static JSBool js_queue_get(JSContext *cx { jsint tiny; msg_queue_t* q; + jsrefcount rc; if((q=(msg_queue_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -349,13 +367,19 @@ static JSBool js_queue_get(JSContext *cx *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,q->name)); break; case QUEUE_PROP_DATA_WAITING: + rc=JS_SUSPENDREQUEST(cx); *vp = BOOLEAN_TO_JSVAL(INT_TO_BOOL(msgQueueReadLevel(q))); + JS_RESUMEREQUEST(cx, rc); break; case QUEUE_PROP_READ_LEVEL: + rc=JS_SUSPENDREQUEST(cx); *vp = INT_TO_JSVAL(msgQueueReadLevel(q)); + JS_RESUMEREQUEST(cx, rc); break; case QUEUE_PROP_WRITE_LEVEL: + rc=JS_SUSPENDREQUEST(cx); *vp = INT_TO_JSVAL(msgQueueWriteLevel(q)); + JS_RESUMEREQUEST(cx, rc); break; } return(JS_TRUE); @@ -373,19 +397,6 @@ static jsSyncPropertySpec js_queue_prope {0} }; -static JSClass js_queue_class = { - "Queue" /* name */ - ,JSCLASS_HAS_PRIVATE /* flags */ - ,JS_PropertyStub /* addProperty */ - ,JS_PropertyStub /* delProperty */ - ,js_queue_get /* getProperty */ - ,JS_PropertyStub /* setProperty */ - ,JS_EnumerateStub /* enumerate */ - ,JS_ResolveStub /* resolve */ - ,JS_ConvertStub /* convert */ - ,js_finalize_queue /* finalize */ -}; - static jsSyncMethodSpec js_queue_functions[] = { {"poll", js_poll, 1, JSTYPE_UNDEF, "[timeout=0]" ,JSDOCSTR("wait for any value to be written to the queue for up to timeout milliseconds " @@ -411,6 +422,34 @@ static jsSyncMethodSpec js_queue_functio {0} }; +static JSBool js_queue_resolve(JSContext *cx, JSObject *obj, jsval id) +{ + char* name=NULL; + + if(id != JSVAL_NULL) + name=JS_GetStringBytes(JSVAL_TO_STRING(id)); + + return(js_SyncResolve(cx, obj, name, js_queue_properties, js_queue_functions, NULL, 0)); +} + +static JSBool js_queue_enumerate(JSContext *cx, JSObject *obj) +{ + return(js_queue_resolve(cx, obj, JSVAL_NULL)); +} + +static JSClass js_queue_class = { + "Queue" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_queue_get /* getProperty */ + ,JS_PropertyStub /* setProperty */ + ,js_queue_enumerate /* enumerate */ + ,js_queue_resolve /* resolve */ + ,JS_ConvertStub /* convert */ + ,js_finalize_queue /* finalize */ +}; + /* Queue Constructor (creates queue) */ static JSBool @@ -421,6 +460,7 @@ js_queue_constructor(JSContext *cx, JSOb int32 flags=MSG_QUEUE_BIDIR; msg_queue_t* q=NULL; list_node_t* n; + jsrefcount rc; *rval = JSVAL_VOID; @@ -438,10 +478,13 @@ js_queue_constructor(JSContext *cx, JSOb if(argnnext) if((q=n->data)!=NULL && !stricmp(q->name,name)) break; + listUnlock(&named_queues); if(n==NULL) q=NULL; } @@ -453,22 +496,13 @@ js_queue_constructor(JSContext *cx, JSOb listPushNode(&named_queues,q); } else msgQueueAttach(q); + JS_RESUMEREQUEST(cx, rc); if(!JS_SetPrivate(cx, obj, q)) { JS_ReportError(cx,"JS_SetPrivate failed"); return(JS_FALSE); } - if(!js_DefineSyncProperties(cx, obj, js_queue_properties)) { - JS_ReportError(cx,"js_DefineSyncProperties failed"); - return(JS_FALSE); - } - - if(!js_DefineSyncMethods(cx, obj, js_queue_functions, FALSE)) { - JS_ReportError(cx,"js_DefineSyncMethods failed"); - return(JS_FALSE); - } - #ifdef BUILD_JSDOCS js_DescribeSyncObject(cx,obj,"Class for bi-directional message queues. " "Used for inter-thread/module communications.", 312); @@ -509,15 +543,9 @@ JSObject* DLLCALL js_CreateQueueObject(J if(obj==NULL) return(NULL); - if(!js_DefineSyncProperties(cx, obj, js_queue_properties)) - return(NULL); - if(!JS_SetPrivate(cx, obj, q)) return(NULL); - if (!js_DefineSyncMethods(cx, obj, js_queue_functions, FALSE)) - return(NULL); - return(obj); }