/** socket_poll_events : 'poll -> timeout:float -> void <doc> Update the read/write flags arrays that were created with [socket_poll_prepare]. </doc> **/ static value socket_poll_events( value pdata, value timeout ) { polldata *p; # ifdef NEKO_WINDOWS unsigned int i; int k = 0; struct timeval t; val_check_kind(pdata,k_poll); p = val_poll(pdata); memcpy(p->outr,p->fdr,FDSIZE(p->fdr->fd_count)); memcpy(p->outw,p->fdw,FDSIZE(p->fdw->fd_count)); val_check(timeout,number); init_timeval(val_number(timeout),&t); gc_enter_blocking(); if( p->fdr->fd_count + p->fdw->fd_count != 0 && select(0,p->outr,p->outw,NULL,&t) == SOCKET_ERROR ) { gc_exit_blocking(); return alloc_null(); } gc_exit_blocking(); k = 0; for(i=0;i<p->fdr->fd_count;i++) if( FD_ISSET(p->fdr->fd_array[i],p->outr) ) val_array_set_i(p->ridx,k++,alloc_int(i)); val_array_set_i(p->ridx,k,alloc_int(-1)); k = 0; for(i=0;i<p->fdw->fd_count;i++) if( FD_ISSET(p->fdw->fd_array[i],p->outw) ) val_array_set_i(p->widx,k++, alloc_int(i)); val_array_set_i(p->widx,k,alloc_int(-1)); #else int i,k; int tot; val_check_kind(pdata,k_poll); val_check(timeout,number); p = val_poll(pdata); tot = p->rcount + p->wcount; gc_enter_blocking(); POSIX_LABEL(poll_events_again); if( poll(p->fds,tot,(int)(val_number(timeout) * 1000)) < 0 ) { HANDLE_EINTR(poll_events_again); gc_exit_blocking(); return alloc_null(); } gc_exit_blocking(); k = 0; for(i=0;i<p->rcount;i++) if( p->fds[i].revents & (POLLIN|POLLHUP) ) val_array_set_i(p->ridx,k++,alloc_int(i)); val_array_set_i(p->ridx,k, alloc_int(-1)); k = 0; for(;i<tot;i++) if( p->fds[i].revents & (POLLOUT|POLLHUP) ) val_array_set_i(p->widx,k++, alloc_int(i - p->rcount)); val_array_set_i(p->widx,k, alloc_int(-1)); #endif return val_null; }
/** socket_poll_prepare : 'poll -> read:'socket array -> write:'socket array -> int array array <doc> Prepare a poll for scanning events on sets of sockets. </doc> **/ static value socket_poll_prepare( value pdata, value rsocks, value wsocks ) { polldata *p; int i,len; val_check(rsocks,array); val_check(wsocks,array); val_check_kind(pdata,k_poll); p = val_poll(pdata); len = val_array_size(rsocks); if( len + val_array_size(wsocks) > p->max ) val_throw(alloc_string("Too many sockets in poll")); # ifdef NEKO_WINDOWS for(i=0;i<len;i++) { value s = val_array_ptr(rsocks)[i]; val_check_kind(s,k_socket); p->fdr->fd_array[i] = val_sock(s); } p->fdr->fd_count = len; len = val_array_size(wsocks); for(i=0;i<len;i++) { value s = val_array_ptr(wsocks)[i]; val_check_kind(s,k_socket); p->fdw->fd_array[i] = val_sock(s); } p->fdw->fd_count = len; # else for(i=0;i<len;i++) { value s = val_array_ptr(rsocks)[i]; val_check_kind(s,k_socket); p->fds[i].fd = val_sock(s); p->fds[i].events = POLLIN; p->fds[i].revents = 0; } p->rcount = len; len = val_array_size(wsocks); for(i=0;i<len;i++) { int k = i + p->rcount; value s = val_array_ptr(wsocks)[i]; val_check_kind(s,k_socket); p->fds[k].fd = val_sock(s); p->fds[k].events = POLLOUT; p->fds[k].revents = 0; } p->wcount = len; # endif { value a = alloc_array(2); val_array_ptr(a)[0] = p->ridx; val_array_ptr(a)[1] = p->widx; return a; } }
/** socket_poll : 'socket array -> 'poll -> timeout:float -> 'socket array <doc> Perform a polling for data available over a given set of sockets. This is similar to [socket_select] except that [socket_select] is limited to a given number of simultaneous sockets to check. </doc> **/ static value socket_poll( value socks, value pdata, value timeout ) { polldata *p; value a; int i, rcount = 0; if( val_is_null( socket_poll_prepare(pdata,socks,alloc_array(0))) ) return alloc_null(); socket_poll_events(pdata,timeout); p = val_poll(pdata); while( val_int(val_array_i(p->ridx,rcount)) != -1 ) rcount++; a = alloc_array(rcount); for(i=0;i<rcount;i++) val_array_set_i(a,i, val_array_i(socks,val_int(val_array_i(p->ridx,i)))); return a; }
/** socket_poll : 'socket array -> 'poll -> timeout:float -> 'socket array <doc> Perform a polling for data available over a given set of sockets. This is similar to [socket_select] except that [socket_select] is limited to a given number of simultaneous sockets to check. </doc> **/ static value socket_poll( value socks, value pdata, value timeout ) { polldata *p; value a; int i, rcount = 0; if( socket_poll_prepare(pdata,socks,alloc_array(0)) == NULL ) neko_error(); if( socket_poll_events(pdata,timeout) == NULL ) neko_error(); p = val_poll(pdata); while( val_array_ptr(p->ridx)[rcount] != alloc_int(-1) ) rcount++; a = alloc_array(rcount); for(i=0;i<rcount;i++) val_array_ptr(a)[i] = val_array_ptr(socks)[val_int(val_array_ptr(p->ridx)[i])]; return a; }