diff --git a/src/build/Common.gmake b/src/build/Common.gmake index f477d9d787013f46ed615147f49f9c13380679af..f370cb1404379b4b884c935e21b7e87b4be37b90 100644 --- a/src/build/Common.gmake +++ b/src/build/Common.gmake @@ -214,6 +214,10 @@ ifndef os endif os := $(shell echo $(os) | tr '[A-Z]' '[a-z]' | tr ' ' '_') +ifneq ($(os),Win32) + CFLAGS += -DPREFER_POLL +endif + machine := $(shell if uname -m | egrep -v "(i[3456789]*|x)86" > /dev/null; then uname -m | tr "[A-Z]" "[a-z]" | tr " " "_" ; fi) machine := $(shell if uname -m | egrep "64" > /dev/null; then uname -m | tr "[A-Z]" "[a-z]" | tr " " "_" ; else echo $(machine) ; fi) ifeq ($(os),darwin) diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c index ee90b87355f9dcd3dda3c83f7fa6a2749f7ece59..32ac501e28b4ee96a5640303ea3f7f21a8bf438c 100644 --- a/src/sbbs3/js_global.c +++ b/src/sbbs3/js_global.c @@ -3695,19 +3695,19 @@ js_socket_select(JSContext *cx, uintN argc, jsval *arglist) JSObject* robj; JSObject* rarray; BOOL poll_for_write=FALSE; -#ifdef _WIN32 - fd_set socket_set[3]; - fd_set* sets[3] = {NULL, NULL, NULL}; - SOCKET maxsock=0; - struct timeval tv = {0, 0}; - SOCKET sock; -#else +#ifdef PREFER_POLL struct pollfd *fds; int poll_timeout = 0; nfds_t nfds; short events; int scount; int k; +#else + fd_set socket_set[3]; + fd_set* sets[3] = {NULL, NULL, NULL}; + SOCKET maxsock=0; + struct timeval tv = {0, 0}; + SOCKET sock; #endif uintN argn; jsuint i; @@ -3726,12 +3726,12 @@ js_socket_select(JSContext *cx, uintN argc, jsval *arglist) poll_for_write=JSVAL_TO_BOOLEAN(argv[argn]); else if(JSVAL_IS_OBJECT(argv[argn])) inarray[inarray_cnt++] = JSVAL_TO_OBJECT(argv[argn]); -#ifdef _WIN32 +#ifdef PREFER_POLL else if(JSVAL_IS_NUMBER(argv[argn])) - js_timeval(cx,argv[argn],&tv); + poll_timeout = js_polltimeout(cx, argv[argn]); #else else if(JSVAL_IS_NUMBER(argv[argn])) - poll_timeout = js_polltimeout(cx, argv[argn]); + js_timeval(cx,argv[argn],&tv); #endif } @@ -3753,42 +3753,7 @@ js_socket_select(JSContext *cx, uintN argc, jsval *arglist) /* Return array */ if((robj = JS_NewArrayObject(cx, 0, NULL))==NULL) return(JS_FALSE); -#ifdef _WIN32 - 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[0];i++) { - if(!JS_GetElement(cx, inarray[0], 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,sets[0],sets[1],sets[2],&tv) >= 0) { - for(i=0;i<limit[0];i++) { - if(!JS_GetElement(cx, inarray[0], 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); - } - } - - JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(robj)); - } -#else +#ifdef PREFER_POLL // First, count the number of sockets... nfds = 0; for (i = 0; i < limit[0]; i++) { @@ -3837,66 +3802,51 @@ js_socket_select(JSContext *cx, uintN argc, jsval *arglist) JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(robj)); } free(fds); -#endif - JS_RESUMEREQUEST(cx, rc); +#else + FD_ZERO(&socket_set[0]); + if(poll_for_write) + sets[1]=&socket_set[0]; + else + sets[0]=&socket_set[0]; - return(JS_TRUE); - } - else { - /* Return object */ - if((robj = JS_NewObject(cx, NULL, NULL, NULL))==NULL) - return(JS_FALSE); -#ifdef _WIN32 - 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; - } - } + for(i=0;i<limit[0];i++) { + if(!JS_GetElement(cx, inarray[0], 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,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[0];i++) { + if(!JS_GetElement(cx, inarray[0], i, &val)) + break; + if(js_socket_isset(cx,val,&socket_set[0])) { + val=INT_TO_JSVAL(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)) - return JS_FALSE; - rc=JS_SUSPENDREQUEST(cx); - for(i=0;i<limit[j];i++) { - JS_RESUMEREQUEST(cx, rc); - if(!JS_GetElement(cx, inarray[j], i, &val)) { - rc=JS_SUSPENDREQUEST(cx); - break; - } + if(!JS_SetElement(cx, robj, len++, &val)) { 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); - } + break; } + rc=JS_SUSPENDREQUEST(cx); } } + JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(robj)); } -#else +#endif + JS_RESUMEREQUEST(cx, rc); + + return(JS_TRUE); + } + else { + /* Return object */ + if((robj = JS_NewObject(cx, NULL, NULL, NULL))==NULL) + return(JS_FALSE); +#ifdef PREFER_POLL /* * So, we need to collapse all the FDs into a list with flags set... * readfd corresponds to POLLIN @@ -4011,6 +3961,56 @@ js_socket_select(JSContext *cx, uintN argc, jsval *arglist) JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(robj)); } free(fds); +#else + 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; + } + } + } + } + + 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; + 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)) + return JS_FALSE; + rc=JS_SUSPENDREQUEST(cx); + for(i=0;i<limit[j];i++) { + JS_RESUMEREQUEST(cx, rc); + 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)); + } #endif JS_RESUMEREQUEST(cx, rc); diff --git a/src/sbbs3/js_socket.c b/src/sbbs3/js_socket.c index 4d732b24f65206fc5d00e6c15e6ca434e0647c6c..6e3d582c723d199bb7844508b749850b3aa220c3 100644 --- a/src/sbbs3/js_socket.c +++ b/src/sbbs3/js_socket.c @@ -472,14 +472,15 @@ SOCKET DLLCALL js_socket(JSContext *cx, jsval val) return(sock); } -#ifdef _WIN32 -SOCKET DLLCALL js_socket_add(JSContext *cx, jsval val, fd_set *fds) +#ifdef PREFER_POLL +size_t DLLCALL js_socket_numsocks(JSContext *cx, jsval val) { js_socket_private_t *p; JSClass* cl; SOCKET sock=INVALID_SOCKET; size_t i; int32_t intval; + size_t ret = 0; if(JSVAL_IS_OBJECT(val) && (cl=JS_GetClass(cx,JSVAL_TO_OBJECT(val)))!=NULL) { if(cl->flags&JSCLASS_HAS_PRIVATE) { @@ -488,33 +489,33 @@ SOCKET DLLCALL js_socket_add(JSContext *cx, jsval val, fd_set *fds) for(i=0; i<p->set->sock_count; i++) { if(p->set->socks[i].sock == INVALID_SOCKET) continue; - FD_SET(p->set->socks[i].sock, fds); - if(p->set->socks[i].sock > sock) - sock = p->set->socks[i].sock; + ret++; } } else { sock = p->sock; if(sock != INVALID_SOCKET) - FD_SET(p->sock, fds); + ret = 1; } } } } else if(val!=JSVAL_VOID) { if(JS_ValueToInt32(cx,val,&intval)) { - sock = intval; - FD_SET(sock, fds); + if (intval != INVALID_SOCKET) + ret = 1; } } - return sock; + return ret; } -BOOL DLLCALL js_socket_isset(JSContext *cx, jsval val, fd_set *fds) +size_t DLLCALL js_socket_add(JSContext *cx, jsval val, struct pollfd *fds, short events) { js_socket_private_t *p; JSClass* cl; + SOCKET sock=INVALID_SOCKET; size_t i; - int intval; + int32_t intval; + size_t ret = 0; if(JSVAL_IS_OBJECT(val) && (cl=JS_GetClass(cx,JSVAL_TO_OBJECT(val)))!=NULL) { if(cl->flags&JSCLASS_HAS_PRIVATE) { @@ -523,51 +524,38 @@ BOOL DLLCALL js_socket_isset(JSContext *cx, jsval val, fd_set *fds) for(i=0; i<p->set->sock_count; i++) { if(p->set->socks[i].sock == INVALID_SOCKET) continue; - if(FD_ISSET(p->set->socks[i].sock, fds)) - return TRUE; + fds[ret].events = events; + fds[ret++].fd = p->set->socks[i].sock; } } else { - if (p->sock == INVALID_SOCKET) - return TRUE; - else { - if(FD_ISSET(p->sock, fds)) - return TRUE; + sock = p->sock; + if(sock != INVALID_SOCKET) { + fds[ret].events = events; + fds[ret++].fd = sock; } } } } } else if(val!=JSVAL_VOID) { if(JS_ValueToInt32(cx,val,&intval)) { - if(FD_ISSET(intval, fds)) - return TRUE; - } - } - return FALSE; -} - -void DLLCALL js_timeval(JSContext* cx, jsval val, struct timeval* tv) -{ - jsdouble jsd; - - if(JSVAL_IS_INT(val)) - tv->tv_sec = JSVAL_TO_INT(val); - else if(JSVAL_IS_DOUBLE(val)) { - if(JS_ValueToNumber(cx,val,&jsd)) { - tv->tv_sec = (int)jsd; - tv->tv_usec = (int)(jsd*1000000.0)%1000000; + sock = intval; + if(sock != INVALID_SOCKET) { + fds[ret].events = events; + fds[ret++].fd = sock; + } } } + return ret; } #else -size_t DLLCALL js_socket_numsocks(JSContext *cx, jsval val) +SOCKET DLLCALL js_socket_add(JSContext *cx, jsval val, fd_set *fds) { js_socket_private_t *p; JSClass* cl; SOCKET sock=INVALID_SOCKET; size_t i; int32_t intval; - size_t ret = 0; if(JSVAL_IS_OBJECT(val) && (cl=JS_GetClass(cx,JSVAL_TO_OBJECT(val)))!=NULL) { if(cl->flags&JSCLASS_HAS_PRIVATE) { @@ -576,33 +564,33 @@ size_t DLLCALL js_socket_numsocks(JSContext *cx, jsval val) for(i=0; i<p->set->sock_count; i++) { if(p->set->socks[i].sock == INVALID_SOCKET) continue; - ret++; + FD_SET(p->set->socks[i].sock, fds); + if(p->set->socks[i].sock > sock) + sock = p->set->socks[i].sock; } } else { sock = p->sock; if(sock != INVALID_SOCKET) - ret = 1; + FD_SET(p->sock, fds); } } } } else if(val!=JSVAL_VOID) { if(JS_ValueToInt32(cx,val,&intval)) { - if (intval != INVALID_SOCKET) - ret = 1; + sock = intval; + FD_SET(sock, fds); } } - return ret; + return sock; } -size_t DLLCALL js_socket_add(JSContext *cx, jsval val, struct pollfd *fds, short events) +BOOL DLLCALL js_socket_isset(JSContext *cx, jsval val, fd_set *fds) { js_socket_private_t *p; JSClass* cl; - SOCKET sock=INVALID_SOCKET; size_t i; - int32_t intval; - size_t ret = 0; + int intval; if(JSVAL_IS_OBJECT(val) && (cl=JS_GetClass(cx,JSVAL_TO_OBJECT(val)))!=NULL) { if(cl->flags&JSCLASS_HAS_PRIVATE) { @@ -611,29 +599,41 @@ size_t DLLCALL js_socket_add(JSContext *cx, jsval val, struct pollfd *fds, short for(i=0; i<p->set->sock_count; i++) { if(p->set->socks[i].sock == INVALID_SOCKET) continue; - fds[ret].events = events; - fds[ret++].fd = p->set->socks[i].sock; + if(FD_ISSET(p->set->socks[i].sock, fds)) + return TRUE; } } else { - sock = p->sock; - if(sock != INVALID_SOCKET) { - fds[ret].events = events; - fds[ret++].fd = sock; + if (p->sock == INVALID_SOCKET) + return TRUE; + else { + if(FD_ISSET(p->sock, fds)) + return TRUE; } } } } } else if(val!=JSVAL_VOID) { if(JS_ValueToInt32(cx,val,&intval)) { - sock = intval; - if(sock != INVALID_SOCKET) { - fds[ret].events = events; - fds[ret++].fd = sock; - } + if(FD_ISSET(intval, fds)) + return TRUE; + } + } + return FALSE; +} + +void DLLCALL js_timeval(JSContext* cx, jsval val, struct timeval* tv) +{ + jsdouble jsd; + + if(JSVAL_IS_INT(val)) + tv->tv_sec = JSVAL_TO_INT(val); + else if(JSVAL_IS_DOUBLE(val)) { + if(JS_ValueToNumber(cx,val,&jsd)) { + tv->tv_sec = (int)jsd; + tv->tv_usec = (int)(jsd*1000000.0)%1000000; } } - return ret; } #endif @@ -1730,18 +1730,18 @@ js_poll(JSContext *cx, uintN argc, jsval *arglist) uintN argn; int result; jsrefcount rc; -#ifdef _WIN32 +#ifdef PREFER_POLL + int timeout = 0; + struct pollfd *fds; + nfds_t nfds; + jsval objval = OBJECT_TO_JSVAL(obj); +#else size_t i; SOCKET high=0; fd_set socket_set; fd_set* rd_set=NULL; fd_set* wr_set=NULL; struct timeval tv = {0, 0}; -#else - int timeout = 0; - struct pollfd *fds; - nfds_t nfds; - jsval objval = OBJECT_TO_JSVAL(obj); #endif JS_SET_RVAL(cx, arglist, JSVAL_VOID); @@ -1760,16 +1760,33 @@ js_poll(JSContext *cx, uintN argc, jsval *arglist) if(JSVAL_IS_BOOLEAN(argv[argn])) poll_for_write=JSVAL_TO_BOOLEAN(argv[argn]); else if(JSVAL_IS_NUMBER(argv[argn])) { -#ifdef _WIN32 - js_timeval(cx,argv[argn],&tv); -#else +#ifdef PREFER_POLL timeout = js_polltimeout(cx, argv[argn]); +#else + js_timeval(cx,argv[argn],&tv); #endif } } rc=JS_SUSPENDREQUEST(cx); -#ifdef _WIN32 +#ifdef PREFER_POLL + if (p->peeked && !poll_for_write) { + result = 1; + } + else { + nfds = js_socket_numsocks(cx, objval); + fds = calloc(nfds, sizeof(*fds)); + if (fds == NULL) { + JS_RESUMEREQUEST(cx, rc); + JS_ReportError(cx, "Error allocating %d elements of %lu bytes at %s:%d" + , nfds, sizeof(*fds), getfname(__FILE__), __LINE__); + return JS_FALSE; + } + nfds = js_socket_add(cx, objval, fds, poll_for_write ? POLLOUT : POLLIN); + result = poll(fds, nfds, timeout); + free(fds); + } +#else FD_ZERO(&socket_set); if(p->set) { for(i=0; i<p->set->sock_count; i++) { @@ -1791,23 +1808,6 @@ js_poll(JSContext *cx, uintN argc, jsval *arglist) result = 1; else result = select(high+1,rd_set,wr_set,NULL,&tv); -#else - if (p->peeked && !poll_for_write) { - result = 1; - } - else { - nfds = js_socket_numsocks(cx, objval); - fds = calloc(nfds, sizeof(*fds)); - if (fds == NULL) { - JS_RESUMEREQUEST(cx, rc); - JS_ReportError(cx, "Error allocating %d elements of %lu bytes at %s:%d" - , nfds, sizeof(*fds), getfname(__FILE__), __LINE__); - return JS_FALSE; - } - nfds = js_socket_add(cx, objval, fds, poll_for_write ? POLLOUT : POLLIN); - result = poll(fds, nfds, timeout); - free(fds); - } #endif p->last_error=ERROR_VALUE; diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index f8b46fa74519c4d929adb793341d7c458f84c5e6..a030e9e22da628684f24ff7ab48029a256c716f4 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -1870,9 +1870,14 @@ void input_thread(void *arg) ulong total_pkts=0; sbbs_t* sbbs = (sbbs_t*) arg; SOCKET sock; -#ifndef _WIN32 +#ifdef PREFER_POLL struct pollfd fds[2]; int nfds; +#else + fd_set socket_set; + struct timeval tv; + SOCKET high_socket; + SOCKET sock; #endif SetThreadName("sbbs/termInput"); @@ -1890,7 +1895,7 @@ void input_thread(void *arg) if(pthread_mutex_lock(&sbbs->input_thread_mutex)!=0) sbbs->errormsg(WHERE,ERR_LOCK,"input_thread_mutex",0); -#ifdef _WIN32 +#ifdef _WIN32 // No spy sockets if (!socket_readable(sbbs->client_socket, 1000)) { if(pthread_mutex_unlock(&sbbs->input_thread_mutex)!=0) sbbs->errormsg(WHERE,ERR_UNLOCK,"input_thread_mutex",0); @@ -1898,6 +1903,7 @@ void input_thread(void *arg) continue; /* to allow other threads to lock the input_thread_mutex */ } #else +#ifdef PREFER_POLL fds[0].fd = sbbs->client_socket; fds[0].events = POLLIN; fds[0].revents = 0; @@ -1915,6 +1921,9 @@ void input_thread(void *arg) YIELD(); /* This kludge is necessary on some Linux distros */ continue; /* to allow other threads to lock the input_thread_mutex */ } +#else +#error Spy sockets without poll() was removed in commit 3971ef4dcc3db19f400a648b6110718e56a64cf3 +#endif #endif if(sbbs->client_socket==INVALID_SOCKET) { @@ -1934,12 +1943,13 @@ void input_thread(void *arg) * ------------ */ -#ifdef _WIN32 +#ifdef _WIN32 // No spy sockets sock=sbbs->client_socket; #else - if (fds[0].revents | POLLIN) +#ifdef PREFER_POLL + if (fds[0].revents & POLLIN) sock = sbbs->client_socket; - else if(uspy_socket[sbbs->cfg.node_num - 1] != INVALID_SOCKET && fds[1].revents | POLLIN) { + else if(uspy_socket[sbbs->cfg.node_num - 1] != INVALID_SOCKET && fds[1].revents & POLLIN) { if(socket_recvdone(uspy_socket[sbbs->cfg.node_num-1], 0)) { close_socket(uspy_socket[sbbs->cfg.node_num-1]); lprintf(LOG_NOTICE,"Closing local spy socket: %d",uspy_socket[sbbs->cfg.node_num-1]); @@ -1955,6 +1965,9 @@ void input_thread(void *arg) sbbs->errormsg(WHERE,ERR_UNLOCK,"input_thread_mutex",0); continue; } +#else +#error Spy sockets without poll() was removed in commit 3971ef4dcc3db19f400a648b6110718e56a64cf3 +#endif #endif rd=RingBufFree(&sbbs->inbuf); diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index de4db437bc56992439a41af619503881e418a1fc..ff71c7fba647e17a3fa9be3b257ddc56a36a7178 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -1354,13 +1354,13 @@ extern "C" { DLLEXPORT SOCKET DLLCALL js_socket(JSContext *cx, jsval val); DLLEXPORT int js_polltimeout(JSContext* cx, jsval val); -#ifdef _WIN32 +#ifdef PREFER_POLL + DLLEXPORT size_t js_socket_numsocks(JSContext *cx, jsval val); + DLLEXPORT size_t js_socket_add(JSContext *cx, jsval val, struct pollfd *fds, short events); +#else DLLEXPORT void DLLCALL js_timeval(JSContext* cx, jsval val, struct timeval* tv); DLLEXPORT SOCKET DLLCALL js_socket_add(JSContext *cx, jsval val, fd_set *fds); DLLEXPORT BOOL DLLCALL js_socket_isset(JSContext *cx, jsval val, fd_set *fds); -#else - DLLEXPORT size_t js_socket_numsocks(JSContext *cx, jsval val); - DLLEXPORT size_t js_socket_add(JSContext *cx, jsval val, struct pollfd *fds, short events); #endif /* js_queue.c */ diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c index 618dd8cc9593615a527c56d5548a1c1705432359..a27eb58aa8aed63a7201ce502681ecf3c0e142c2 100644 --- a/src/sbbs3/services.c +++ b/src/sbbs3/services.c @@ -1722,7 +1722,7 @@ void service_udp_sock_cb(SOCKET sock, void *cbdata) #endif } -#ifndef _WIN32 +#ifdef PREFER_POLL /* * Sets up the fds for poll, and returns the total sockets */ @@ -1787,14 +1787,14 @@ void DLLCALL services_thread(void* arg) char *ssl_estr; int level; BOOL need_cert = FALSE; -#ifdef _WIN32 - fd_set socket_set; - SOCKET high_socket; - struct timeval tv; -#else +#ifdef PREFER_POLL struct pollfd *fds = NULL; nfds_t nfds; nfds_t nfdsi; +#else + fd_set socket_set; + SOCKET high_socket; + struct timeval tv; #endif startup=(services_startup_t*)arg; @@ -2001,7 +2001,7 @@ void DLLCALL services_thread(void* arg) lprintf(LOG_INFO,"0000 Services thread started (%lu service sockets bound)", total_sockets); -#ifndef _WIN32 +#ifdef PREFER_POLL nfds = setup_poll(&fds); if (nfds == 0) { lprintf(LOG_CRIT, "!ERROR setting up poll() data"); @@ -2034,92 +2034,92 @@ void DLLCALL services_thread(void* arg) } } -#ifdef _WIN32 - /* Setup select() parms */ - FD_ZERO(&socket_set); - high_socket=0; +#ifdef PREFER_POLL + /* Clear poll FDs where necessary (ie: when !SERVICE_OPT_FULL_ACCEPT) */ + nfdsi = 0; for(i=0;i<(int)services;i++) { if(service[i].options&SERVICE_OPT_STATIC) continue; if(service[i].set==NULL) continue; - if(!(service[i].options&SERVICE_OPT_FULL_ACCEPT) - && service[i].max_clients && protected_uint32_value(service[i].clients) >= service[i].max_clients) - continue; - for(j=0; j<service[i].set->sock_count; j++) { - FD_SET(service[i].set->socks[j].sock,&socket_set); - if(service[i].set->socks[j].sock>high_socket) - high_socket=service[i].set->socks[j].sock; + if(!(service[i].options&SERVICE_OPT_FULL_ACCEPT)) { + if (service[i].max_clients && protected_uint32_value(service[i].clients) >= service[i].max_clients) { + for(j=0; j<service[i].set->sock_count; j++) + fds[nfdsi + j].fd = -1; + } + else { + for(j=0; j<service[i].set->sock_count; j++) + fds[nfdsi + j].fd = service[i].set->socks[j].sock; + } } + nfdsi += service[i].set->sock_count; } - if(high_socket==0) /* No dynamic services? */ - continue; - tv.tv_sec=startup->sem_chk_freq; - tv.tv_usec=0; - if((result=select(high_socket+1,&socket_set,NULL,NULL,&tv))<1) { + + if ((result = poll(fds, nfds, startup->sem_chk_freq * 1000)) < 1) { if(result==0) continue; if(ERROR_VALUE==EINTR) lprintf(LOG_DEBUG,"0000 Services listening interrupted"); - else if(ERROR_VALUE == ENOTSOCK) - lprintf(LOG_NOTICE,"0000 Services sockets closed"); else - lprintf(LOG_WARNING,"0000 !ERROR %d selecting sockets: %s" + lprintf(LOG_WARNING,"0000 !ERROR %d polling sockets: %s" , ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error))); continue; } - - /* Determine who services this socket */ + nfdsi = 0; for(i=0;i<(int)services;i++) { - + if(service[i].options&SERVICE_OPT_STATIC) + continue; if(service[i].set==NULL) continue; for(j=0; j<service[i].set->sock_count; j++) { - if(!FD_ISSET(service[i].set->socks[j].sock,&socket_set)) + if ((fds[nfdsi + j].revents & POLLIN) == 0) continue; #else - /* Clear poll FDs where necessary (ie: when !SERVICE_OPT_FULL_ACCEPT) */ - nfdsi = 0; + /* Setup select() parms */ + FD_ZERO(&socket_set); + high_socket=0; for(i=0;i<(int)services;i++) { if(service[i].options&SERVICE_OPT_STATIC) continue; if(service[i].set==NULL) continue; - if(!(service[i].options&SERVICE_OPT_FULL_ACCEPT)) { - if (service[i].max_clients && protected_uint32_value(service[i].clients) >= service[i].max_clients) { - for(j=0; j<service[i].set->sock_count; j++) - fds[nfdsi + j].fd = -1; - } - else { - for(j=0; j<service[i].set->sock_count; j++) - fds[nfdsi + j].fd = service[i].set->socks[j].sock; - } + if(!(service[i].options&SERVICE_OPT_FULL_ACCEPT) + && service[i].max_clients && protected_uint32_value(service[i].clients) >= service[i].max_clients) + continue; + for(j=0; j<service[i].set->sock_count; j++) { + FD_SET(service[i].set->socks[j].sock,&socket_set); + if(service[i].set->socks[j].sock>high_socket) + high_socket=service[i].set->socks[j].sock; } - nfdsi += service[i].set->sock_count; } - - if ((result = poll(fds, nfds, startup->sem_chk_freq * 1000)) < 1) { + if(high_socket==0) /* No dynamic services? */ + continue; + tv.tv_sec=startup->sem_chk_freq; + tv.tv_usec=0; + if((result=select(high_socket+1,&socket_set,NULL,NULL,&tv))<1) { if(result==0) continue; if(ERROR_VALUE==EINTR) lprintf(LOG_DEBUG,"0000 Services listening interrupted"); + else if(ERROR_VALUE == ENOTSOCK) + lprintf(LOG_NOTICE,"0000 Services sockets closed"); else - lprintf(LOG_WARNING,"0000 !ERROR %d polling sockets: %s" + lprintf(LOG_WARNING,"0000 !ERROR %d selecting sockets: %s" , ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error))); continue; } - nfdsi = 0; + + /* Determine who services this socket */ for(i=0;i<(int)services;i++) { - if(service[i].options&SERVICE_OPT_STATIC) - continue; + if(service[i].set==NULL) continue; for(j=0; j<service[i].set->sock_count; j++) { - if ((fds[nfdsi + j].revents & POLLIN) == 0) + if(!FD_ISSET(service[i].set->socks[j].sock,&socket_set)) continue; #endif client_addr_len = sizeof(client_addr); @@ -2296,12 +2296,12 @@ void DLLCALL services_thread(void* arg) service[i].served++; served++; } -#ifndef _WIN32 +#ifdef PREFER_POLL nfdsi += service[i].set->sock_count; #endif } } -#ifndef _WIN32 +#ifdef PREFER_POLL free(fds); #endif diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp index e4039fe179f3feffbe29af5722cf77db0cea2d76..885b498936f212a7ad7d03aad757a5ed22b4eb96 100644 --- a/src/sbbs3/xtrn.cpp +++ b/src/sbbs3/xtrn.cpp @@ -1072,7 +1072,11 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) BYTE wwiv_buf[XTRN_IO_BUF_LEN*2]; bool wwiv_flag=false; char* p; +#ifdef PREFER_POLL struct pollfd fds[2]; +#else +#error select() implementation was removed in 3971ef4d +#endif xtrn_mode = mode; lprintf(LOG_DEBUG, "Executing external: %s", cmdline); diff --git a/src/xpdev/multisock.c b/src/xpdev/multisock.c index 676c5ed74fdb460c5dc8d5badcd9a6729cccf03a..5f5ce5ac908f1bf4e9fd234e6867d5991f1729e0 100644 --- a/src/xpdev/multisock.c +++ b/src/xpdev/multisock.c @@ -312,15 +312,15 @@ static BOOL read_socket_line(SOCKET sock, char *buffer, size_t buflen, int (*lpr SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, socklen_t * addrlen, unsigned int timeout, uint32_t flags, void **cb_data) { -#ifdef _WIN32 // Use select() +#ifdef PREFER_POLL + struct pollfd *fds; + int poll_timeout; + nfds_t scnt = 0; +#else fd_set read_fs; struct timeval tv; struct timeval *tvp; SOCKET max_sock=0; -#else // Use poll() - struct pollfd *fds; - int poll_timeout; - nfds_t scnt = 0; #endif size_t i; SOCKET ret; @@ -333,34 +333,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, if (xpms_set->sock_count < 1) return INVALID_SOCKET; -#ifdef _WIN32 - FD_ZERO(&read_fs); - for(i=0; i<xpms_set->sock_count; i++) { - if(xpms_set->socks[i].sock == INVALID_SOCKET) - continue; - FD_SET(xpms_set->socks[i].sock, &read_fs); - if(xpms_set->socks[i].sock >= max_sock) - max_sock=xpms_set->socks[i].sock+1; - } - - if(timeout==XPMS_FOREVER) - tvp=NULL; - else { - tv.tv_sec=timeout/1000; - tv.tv_usec=(timeout%1000)*1000; - tvp=&tv; - } - switch(select(max_sock, &read_fs, NULL, NULL, tvp)) { - case 0: - return INVALID_SOCKET; - case -1: - return SOCKET_ERROR; - default: - for(i=0; i<xpms_set->sock_count; i++) { - if(xpms_set->socks[i].sock == INVALID_SOCKET) - continue; - if(FD_ISSET(xpms_set->socks[i].sock, &read_fs)) { -#else +#ifdef PREFER_POLL fds = calloc(xpms_set->sock_count, sizeof(*fds)); if (fds == NULL) return INVALID_SOCKET; @@ -399,6 +372,33 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, continue; } if (fds[scnt++].revents & POLLIN) { +#else + FD_ZERO(&read_fs); + for(i=0; i<xpms_set->sock_count; i++) { + if(xpms_set->socks[i].sock == INVALID_SOCKET) + continue; + FD_SET(xpms_set->socks[i].sock, &read_fs); + if(xpms_set->socks[i].sock >= max_sock) + max_sock=xpms_set->socks[i].sock+1; + } + + if(timeout==XPMS_FOREVER) + tvp=NULL; + else { + tv.tv_sec=timeout/1000; + tv.tv_usec=(timeout%1000)*1000; + tvp=&tv; + } + switch(select(max_sock, &read_fs, NULL, NULL, tvp)) { + case 0: + return INVALID_SOCKET; + case -1: + return SOCKET_ERROR; + default: + for(i=0; i<xpms_set->sock_count; i++) { + if(xpms_set->socks[i].sock == INVALID_SOCKET) + continue; + if(FD_ISSET(xpms_set->socks[i].sock, &read_fs)) { #endif if(cb_data) *cb_data=xpms_set->socks[i].cb_data; @@ -620,12 +620,12 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, inet_addrtop(addr, hapstr, sizeof(hapstr)); xpms_set->lprintf(LOG_INFO,"%04d * HAPROXY Source [%s]",ret,hapstr); -#ifndef _WIN32 +#ifdef PREFER_POLL free(fds); #endif return ret; } else { -#ifndef _WIN32 +#ifdef PREFER_POLL free(fds); #endif return ret; @@ -635,7 +635,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, } error_return: -#ifndef _WIN32 +#ifdef PREFER_POLL free(fds); #endif return INVALID_SOCKET; diff --git a/src/xpdev/sockwrap.c b/src/xpdev/sockwrap.c index 76c47aad04067232f928c6c7027753200410765b..eee5ed44398d83493c5256efd34bf8f70ba601e3 100644 --- a/src/xpdev/sockwrap.c +++ b/src/xpdev/sockwrap.c @@ -272,7 +272,58 @@ off_t recvfilesocket(int sock, int file, off_t *offset, off_t count) /* Return true if connected, optionally sets *rd_p to true if read data available */ BOOL socket_check(SOCKET sock, BOOL* rd_p, BOOL* wr_p, DWORD timeout) { -#ifdef _WIN32 +#ifdef PREFER_POLL + struct pollfd pfd = {0}; + int j, rd; + char ch; + + if(rd_p!=NULL) + *rd_p=FALSE; + + if(wr_p!=NULL) + *wr_p=FALSE; + + if(sock==INVALID_SOCKET) + return(FALSE); + + pfd.fd = sock; + pfd.events = POLLIN | POLLHUP; + if (wr_p != NULL) + pfd.events |= POLLOUT; + + j = poll(&pfd, 1, timeout); + + if (j == 0) + return TRUE; + + if (j == 1) { + if (wr_p != NULL && (pfd.revents & POLLOUT)) + *wr_p = TRUE; + if (rd_p != NULL && (pfd.revents & POLLIN)) + *rd_p = TRUE; + + if (pfd.revents & (POLLERR | POLLNVAL)) + return FALSE; + + if(pfd.revents & (POLLIN | POLLHUP) && (rd_p !=NULL || wr_p==NULL)) { + rd=recv(sock,&ch,1,MSG_PEEK); + if(rd==1 || (rd==SOCKET_ERROR && ERROR_VALUE==EMSGSIZE)) { + if(rd_p!=NULL) + *rd_p=TRUE; + return(TRUE); + } + return FALSE; + } + } + + if (j == -1) { + if (errno == EINTR || errno == ENOMEM) + return TRUE; + return FALSE; + } + + return TRUE; +#else char ch; int i,rd; fd_set rd_set; @@ -328,57 +379,6 @@ BOOL socket_check(SOCKET sock, BOOL* rd_p, BOOL* wr_p, DWORD timeout) } return(FALSE); -#else - struct pollfd pfd = {0}; - int j, rd; - char ch; - - if(rd_p!=NULL) - *rd_p=FALSE; - - if(wr_p!=NULL) - *wr_p=FALSE; - - if(sock==INVALID_SOCKET) - return(FALSE); - - pfd.fd = sock; - pfd.events = POLLIN | POLLHUP; - if (wr_p != NULL) - pfd.events |= POLLOUT; - - j = poll(&pfd, 1, timeout); - - if (j == 0) - return TRUE; - - if (j == 1) { - if (wr_p != NULL && (pfd.revents & POLLOUT)) - *wr_p = TRUE; - if (rd_p != NULL && (pfd.revents & POLLIN)) - *rd_p = TRUE; - - if (pfd.revents & (POLLERR | POLLNVAL)) - return FALSE; - - if(pfd.revents & (POLLIN | POLLHUP) && (rd_p !=NULL || wr_p==NULL)) { - rd=recv(sock,&ch,1,MSG_PEEK); - if(rd==1 || (rd==SOCKET_ERROR && ERROR_VALUE==EMSGSIZE)) { - if(rd_p!=NULL) - *rd_p=TRUE; - return(TRUE); - } - return FALSE; - } - } - - if (j == -1) { - if (errno == EINTR || errno == ENOMEM) - return TRUE; - return FALSE; - } - - return TRUE; #endif } @@ -391,7 +391,15 @@ BOOL socket_check(SOCKET sock, BOOL* rd_p, BOOL* wr_p, DWORD timeout) */ BOOL socket_readable(SOCKET sock, int timeout) { -#ifdef _WIN32 +#ifdef PREFER_POLL + struct pollfd pfd = {0}; + pfd.fd = sock; + pfd.events = POLLIN; + + if (poll(&pfd, 1, timeout) == 1) + return TRUE; + return FALSE; +#else fd_set rd_set; struct timeval tv = {0}; struct timeval *tvp = &tv; @@ -413,14 +421,6 @@ BOOL socket_readable(SOCKET sock, int timeout) } // Errors and unexpected cases return TRUE; -#else - struct pollfd pfd = {0}; - pfd.fd = sock; - pfd.events = POLLIN; - - if (poll(&pfd, 1, timeout) == 1) - return TRUE; - return FALSE; #endif } @@ -433,7 +433,15 @@ BOOL socket_readable(SOCKET sock, int timeout) */ BOOL socket_writable(SOCKET sock, int timeout) { -#ifdef _WIN32 +#ifdef PREFER_POLL + struct pollfd pfd = {0}; + pfd.fd = sock; + pfd.events = POLLOUT; + + if (poll(&pfd, 1, timeout) == 1) + return TRUE; + return FALSE; +#else fd_set wr_set; struct timeval tv = {0}; struct timeval *tvp = &tv; @@ -455,14 +463,6 @@ BOOL socket_writable(SOCKET sock, int timeout) } // Errors and unexpected cases return TRUE; -#else - struct pollfd pfd = {0}; - pfd.fd = sock; - pfd.events = POLLOUT; - - if (poll(&pfd, 1, timeout) == 1) - return TRUE; - return FALSE; #endif } @@ -474,7 +474,29 @@ BOOL socket_writable(SOCKET sock, int timeout) */ BOOL socket_recvdone(SOCKET sock, int timeout) { -#ifdef _WIN32 +#ifdef PREFER_POLL + struct pollfd pfd = {0}; + pfd.fd = sock; + pfd.events = POLLIN; + char ch; + int rd; + + switch (poll(&pfd, 1, timeout)) { + case 1: + if (pfd.revents & (POLLIN | POLLHUP)) { + rd = recv(sock,&ch,1,MSG_PEEK); + if (rd == 1 || (rd==SOCKET_ERROR && ERROR_VALUE==EMSGSIZE)) + return FALSE; + return TRUE; + } + return FALSE; + case -1: + if (errno == EINTR || errno == ENOMEM) + return FALSE; + return TRUE; + } + return FALSE; +#else fd_set rd_set; struct timeval tv = {0}; struct timeval *tvp = &tv; @@ -500,28 +522,6 @@ BOOL socket_recvdone(SOCKET sock, int timeout) if (rd == 1 || (rd==SOCKET_ERROR && ERROR_VALUE==EMSGSIZE)) return FALSE; return TRUE; -#else - struct pollfd pfd = {0}; - pfd.fd = sock; - pfd.events = POLLIN; - char ch; - int rd; - - switch (poll(&pfd, 1, timeout)) { - case 1: - if (pfd.revents & (POLLIN | POLLHUP)) { - rd = recv(sock,&ch,1,MSG_PEEK); - if (rd == 1 || (rd==SOCKET_ERROR && ERROR_VALUE==EMSGSIZE)) - return FALSE; - return TRUE; - } - return FALSE; - case -1: - if (errno == EINTR || errno == ENOMEM) - return FALSE; - return TRUE; - } - return FALSE; #endif }