/** socket_poll_alloc : int -> 'poll <doc>Allocate memory to perform polling on a given number of sockets</doc> **/ static value socket_poll_alloc( value nsocks ) { polldata *p; int i; val_check(nsocks,int); p = (polldata*)alloc(sizeof(polldata)); p->max = val_int(nsocks); if( p->max < 0 || p->max > 1000000 ) neko_error(); # ifdef NEKO_WINDOWS { p->fdr = (fd_set*)alloc_private(FDSIZE(p->max)); p->fdw = (fd_set*)alloc_private(FDSIZE(p->max)); p->outr = (fd_set*)alloc_private(FDSIZE(p->max)); p->outw = (fd_set*)alloc_private(FDSIZE(p->max)); p->fdr->fd_count = 0; p->fdw->fd_count = 0; } # else p->fds = (struct pollfd*)alloc_private(sizeof(struct pollfd) * p->max); p->rcount = 0; p->wcount = 0; # endif p->ridx = alloc_array(p->max+1); p->widx = alloc_array(p->max+1); for(i=0;i<=p->max;i++) { val_array_ptr(p->ridx)[i] = alloc_int(-1); val_array_ptr(p->widx)[i] = alloc_int(-1); } return alloc_abstract(k_poll, p); }
static value socket_poll_alloc( value nsocks ) { polldata *p; int i; val_check(nsocks,int); p = (polldata*)malloc(sizeof(polldata)); p->max = val_int(nsocks); if( p->max < 0 || p->max > 1000000 ) return alloc_null(); # ifdef NEKO_WINDOWS { p->fdr = (fd_set*)malloc(FDSIZE(p->max)); p->fdw = (fd_set*)malloc(FDSIZE(p->max)); p->outr = (fd_set*)malloc(FDSIZE(p->max)); p->outw = (fd_set*)malloc(FDSIZE(p->max)); p->fdr->fd_count = 0; p->fdw->fd_count = 0; } # else p->fds = (struct pollfd*)malloc(sizeof(struct pollfd) * p->max); p->rcount = 0; p->wcount = 0; # endif p->ridx = alloc_array(p->max+1); p->widx = alloc_array(p->max+1); val_gc_add_root(&p->ridx); val_gc_add_root(&p->widx); for(i=0;i<=p->max;i++) { val_array_set_i(p->ridx,i, alloc_int(-1)); val_array_set_i(p->widx,i, alloc_int(-1)); } value v = alloc_abstract(k_poll, p); val_gc(v,free_sock); return v; }
/** 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; }
HL_PRIM int hl_socket_fd_size( int size ) { if( size > FD_SETSIZE ) return -1; # ifdef HL_WIN return FDSIZE(size); # else return sizeof(fd_set); # endif }