diff --git a/src/hx/libs/std/Socket.cpp b/src/hx/libs/std/Socket.cpp index fe77cdc46..eafce592b 100644 --- a/src/hx/libs/std/Socket.cpp +++ b/src/hx/libs/std/Socket.cpp @@ -1224,65 +1224,101 @@ Array _hx_std_socket_poll_prepare( Dynamic pdata, Array rsocks Update the read/write flags arrays that were created with [socket_poll_prepare]. **/ -void _hx_std_socket_poll_events( Dynamic pdata, double timeout ) +void _hx_std_socket_poll_events(Dynamic pdata, double timeout) { polldata *p = val_poll(pdata); - #ifdef NEKO_WINDOWS - memcpy(p->outr,p->fdr,FDSIZE(p->fdr->fd_count)); - memcpy(p->outw,p->fdw,FDSIZE(p->fdw->fd_count)); + p->ridx[0] = -1; + p->widx[0] = -1; + +#ifdef NEKO_WINDOWS + memcpy(p->outr, p->fdr, FDSIZE(p->fdr->fd_count)); + memcpy(p->outw, p->fdw, FDSIZE(p->fdw->fd_count)); + + fd_set oute; + FD_ZERO(&oute); + if (p->fdr->fd_count) + { + for (u_int i = 0; i < p->fdr->fd_count; ++i) + FD_SET(p->fdr->fd_array[i], &oute); + } struct timeval t; - struct timeval *tt = init_timeval(timeout,&t); + struct timeval *tt = init_timeval(timeout, &t); hx::EnterGCFreeZone(); - if( select(0/* Ignored */, p->fdr->fd_count ? p->outr : 0, p->fdw->fd_count ?p->outw : 0,NULL,tt) == SOCKET_ERROR ) + int sel = select( + 0, + p->fdr->fd_count ? p->outr : 0, + p->fdw->fd_count ? p->outw : 0, + p->fdr->fd_count ? &oute : 0, + tt); + if (sel == SOCKET_ERROR) { hx::ExitGCFreeZone(); + + int k = 0; + for (u_int i = 0; i < p->fdr->fd_count; ++i) + p->ridx[k++] = i; + p->ridx[k] = -1; + return; } hx::ExitGCFreeZone(); int k = 0; - for(int i=0;ifdr->fd_count;i++) - if( FD_ISSET(p->fdr->fd_array[i],p->outr) ) + for (u_int i = 0; i < p->fdr->fd_count; ++i) + { + SOCKET fd = p->fdr->fd_array[i]; + if (FD_ISSET(fd, p->outr) || FD_ISSET(fd, &oute)) p->ridx[k++] = i; + } p->ridx[k] = -1; k = 0; - for(int i=0;ifdw->fd_count;i++) - if( FD_ISSET(p->fdw->fd_array[i],p->outw) ) + for (u_int i = 0; i < p->fdw->fd_count; ++i) + { + if (FD_ISSET(p->fdw->fd_array[i], p->outw)) p->widx[k++] = i; + } p->widx[k] = -1; - #else - +#else int tot = p->rcount + p->wcount; + hx::EnterGCFreeZone(); - POSIX_LABEL(poll_events_again); - if( poll(p->fds,tot,(int)(timeout * 1000)) < 0 ) +poll_events_again: + if (poll(p->fds, tot, (int)(timeout * 1000)) < 0) { - HANDLE_EINTR(poll_events_again); + if (errno == EINTR) + goto poll_events_again; hx::ExitGCFreeZone(); + return; } hx::ExitGCFreeZone(); int k = 0; int i = 0; - for(i=0;ircount;i++) - if( p->fds[i].revents & (POLLIN|POLLHUP) ) + + for (i = 0; i < p->rcount; ++i) + { + if (p->fds[i].revents & (POLLIN | POLLHUP | POLLERR | POLLNVAL)) p->ridx[k++] = i; + } p->ridx[k] = -1; + k = 0; - for(;ifds[i].revents & (POLLOUT|POLLHUP) ) + + for (; i < tot; ++i) + { + if (p->fds[i].revents & (POLLOUT | POLLHUP | POLLERR | POLLNVAL)) p->widx[k++] = i - p->rcount; + } p->widx[k] = -1; - #endif +#endif } - /** socket_poll : 'socket array -> 'poll -> timeout:float -> 'socket array