--- 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);
}