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

Add an additional for of socket_select() that is passed multiple arrays.

It will return an object with properties corresponding to the passed
arrays, and the write parameter will be ignored.  This allows usage very
much like the select() syscall, and allows a traditional non-blocking
server to be written.
parent bf483f89
No related branches found
No related tags found
No related merge requests found
......@@ -3667,21 +3667,25 @@ static JSBool
js_socket_select(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
JSObject* inarray=NULL;
JSObject* inarray[3]={NULL, NULL, NULL};
int inarray_cnt = 0;
JSObject* robj;
JSObject* rarray;
BOOL poll_for_write=FALSE;
fd_set socket_set;
fd_set* rd_set=NULL;
fd_set* wr_set=NULL;
fd_set socket_set[3];
fd_set* sets[3] = {NULL, NULL, NULL};
uintN argn;
SOCKET sock;
SOCKET maxsock=0;
struct timeval tv = {0, 0};
jsuint i;
jsuint limit;
jsuint j;
jsuint limit[3];
jsval val;
int len=0;
jsrefcount rc;
BOOL all_zero = TRUE;
const char *props[3] = {"read", "write", "except"};
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
......@@ -3689,58 +3693,124 @@ js_socket_select(JSContext *cx, uintN argc, jsval *arglist)
if(JSVAL_IS_BOOLEAN(argv[argn]))
poll_for_write=JSVAL_TO_BOOLEAN(argv[argn]);
else if(JSVAL_IS_OBJECT(argv[argn]))
inarray = JSVAL_TO_OBJECT(argv[argn]);
inarray[inarray_cnt++] = JSVAL_TO_OBJECT(argv[argn]);
else if(JSVAL_IS_NUMBER(argv[argn]))
js_timeval(cx,argv[argn],&tv);
}
if(inarray==NULL || !JS_IsArrayObject(cx, inarray))
if(inarray_cnt == 0)
return(JS_TRUE); /* This not a fatal error */
for (i = 0; i < inarray_cnt; i++) {
if (!JS_IsArrayObject(cx, inarray[i]))
return(JS_TRUE); /* This not a fatal error */
if (JS_GetArrayLength(cx, inarray[i], &limit[i]) != 0)
all_zero = FALSE;
}
if (inarray_cnt > 3)
inarray_cnt = 3;
if(!JS_GetArrayLength(cx, inarray, &limit))
if (all_zero)
return(JS_TRUE);
/* Return array */
if((rarray = JS_NewArrayObject(cx, 0, NULL))==NULL)
return(JS_FALSE);
FD_ZERO(&socket_set);
if(poll_for_write)
wr_set=&socket_set;
else
rd_set=&socket_set;
if (inarray_cnt == 1) {
/* Return array */
if((robj = JS_NewArrayObject(cx, 0, NULL))==NULL)
return(JS_FALSE);
FD_ZERO(&socket_set[0]);
if(poll_for_write)
sets[1]=&socket_set[0];
else
sets[0]=&socket_set[0];
for(i=0;i<limit;i++) {
if(!JS_GetElement(cx, inarray, i, &val))
break;
sock=js_socket_add(cx,val,&socket_set);
if(sock!=INVALID_SOCKET) {
if(sock>maxsock)
maxsock=sock;
for(i=0;i<limit[0];i++) {
if(!JS_GetElement(cx, inarray[i], i, &val))
break;
sock=js_socket_add(cx,val,&socket_set[0]);
if(sock!=INVALID_SOCKET) {
if(sock>maxsock)
maxsock=sock;
}
}
}
rc=JS_SUSPENDREQUEST(cx);
if(select(maxsock+1,rd_set,wr_set,NULL,&tv) >= 0) {
for(i=0;i<limit;i++) {
if(!JS_GetElement(cx, inarray, i, &val))
break;
if(js_socket_isset(cx,val,&socket_set)) {
val=INT_TO_JSVAL(i);
JS_RESUMEREQUEST(cx, rc);
if(!JS_SetElement(cx, rarray, len++, &val)) {
rc=JS_SUSPENDREQUEST(cx);
rc=JS_SUSPENDREQUEST(cx);
if(select(maxsock+1,sets[0],sets[1],sets[2],&tv) >= 0) {
for(i=0;i<limit[0];i++) {
if(!JS_GetElement(cx, inarray[i], i, &val))
break;
if(js_socket_isset(cx,val,&socket_set[0])) {
val=INT_TO_JSVAL(i);
JS_RESUMEREQUEST(cx, rc);
if(!JS_SetElement(cx, robj, len++, &val)) {
rc=JS_SUSPENDREQUEST(cx);
break;
}
rc=JS_SUSPENDREQUEST(cx);
}
rc=JS_SUSPENDREQUEST(cx);
}
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(robj));
}
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(rarray));
return(JS_TRUE);
}
JS_RESUMEREQUEST(cx, rc);
else {
/* Return object */
if((robj = JS_NewObject(cx, NULL, NULL, NULL))==NULL)
return(JS_FALSE);
for (j = 0; j < inarray_cnt; j++) {
if (limit[j] > 0) {
FD_ZERO(&socket_set[j]);
sets[j] = &socket_set[j];
for (i = 0; i < limit[j]; i++) {
if(!JS_GetElement(cx, inarray[j], i, &val))
break;
sock=js_socket_add(cx,val,&socket_set[j]);
if(sock!=INVALID_SOCKET) {
if(sock>maxsock)
maxsock=sock;
}
}
}
}
return(JS_TRUE);
rc=JS_SUSPENDREQUEST(cx);
if(select(maxsock+1,sets[0],sets[1],sets[2],&tv) >= 0) {
for (j = 0; j < inarray_cnt; j++) {
if (limit[j] > 0) {
len = 0;
for(i=0;i<limit[j];i++) {
JS_RESUMEREQUEST(cx, rc);
if((rarray = JS_NewArrayObject(cx, 0, NULL))==NULL)
return(JS_FALSE);
val = OBJECT_TO_JSVAL(rarray);
if (!JS_SetProperty(cx, robj, props[j], &val)) {
rc=JS_SUSPENDREQUEST(cx);
return JS_FALSE;
}
if(!JS_GetElement(cx, inarray[j], i, &val)) {
rc=JS_SUSPENDREQUEST(cx);
break;
}
rc=JS_SUSPENDREQUEST(cx);
if(js_socket_isset(cx,val,&socket_set[j])) {
val=INT_TO_JSVAL(i);
JS_RESUMEREQUEST(cx, rc);
if(!JS_SetElement(cx, rarray, len++, &val)) {
rc=JS_SUSPENDREQUEST(cx);
break;
}
rc=JS_SUSPENDREQUEST(cx);
}
}
}
}
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(robj));
}
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
}
static JSBool
......@@ -4623,7 +4693,10 @@ static jsSyncMethodSpec js_global_functions[] = {
{"socket_select", js_socket_select, 0, JSTYPE_ARRAY, JSDOCSTR("[array of socket objects or descriptors] [,timeout=<tt>0</tt>] [,write=<tt>false</tt>]")
,JSDOCSTR("checks an array of socket objects or descriptors for read or write ability (default is <i>read</i>), "
"default timeout value is 0.0 seconds (immediate timeout), "
"returns an array of 0-based index values into the socket array, representing the sockets that were ready for reading or writing, or <i>null</i> on error")
"returns an array of 0-based index values into the socket array, representing the sockets that were ready for reading or writing, or <i>null</i> on error. "
"If multiple arrays of sockets are passed, they are presumet to be in the order of read, write, and except. In this case, the write parameter is ignored "
"and an object is returned instead with up to three properties \"read\", \"write\", and \"except\", corresponding to the passed arrays. Empty passed "
"arrays will not have a corresponding property in the returned object.")
,311
},
{"mkdir", js_mkdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/directory")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment