forked from Mirrors/freeswitch
105 lines
1.6 KiB
C
105 lines
1.6 KiB
C
#define FD_SETSIZE 256
|
|
|
|
#ifdef __MINGW32__
|
|
#include <winsock2.h>
|
|
#else
|
|
#ifdef __MINGW64__
|
|
#include <winsock2.h>
|
|
#else
|
|
#include <WinSock2.h>
|
|
#endif
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include "websock-w32.h"
|
|
|
|
PFNWSAPOLL poll = NULL;
|
|
|
|
INT WSAAPI emulated_poll(LPWSAPOLLFD fdarray, ULONG nfds, INT timeout)
|
|
{
|
|
fd_set readfds;
|
|
fd_set writefds;
|
|
struct timeval tv;
|
|
struct timeval *ptv = &tv;
|
|
SOCKET max_socket = 0;
|
|
ULONG n = 0;
|
|
int waiting;
|
|
int pending = 0;
|
|
WSAPOLLFD * poll_fd = fdarray;
|
|
|
|
if (NULL == fdarray) {
|
|
errno = EFAULT;
|
|
return -1;
|
|
}
|
|
|
|
FD_ZERO(&readfds);
|
|
FD_ZERO(&writefds);
|
|
|
|
tv.tv_sec = timeout / 1000;
|
|
tv.tv_usec = (timeout % 1000) * 1000;
|
|
|
|
if (timeout < 0)
|
|
ptv = NULL;
|
|
|
|
while (n < nfds) {
|
|
|
|
poll_fd->revents = 0;
|
|
|
|
if (poll_fd->fd < 0 || !poll_fd->events)
|
|
goto skip1;
|
|
|
|
if (max_socket < poll_fd->fd)
|
|
max_socket = poll_fd->fd;
|
|
|
|
if (poll_fd->events & POLLIN)
|
|
FD_SET(poll_fd->fd, &readfds);
|
|
|
|
if (poll_fd->events & POLLOUT)
|
|
FD_SET(poll_fd->fd, &writefds);
|
|
skip1:
|
|
poll_fd++;
|
|
n++;
|
|
}
|
|
|
|
waiting = select((int)max_socket + 1, &readfds, &writefds, NULL, ptv);
|
|
|
|
if (waiting <= 0)
|
|
return waiting;
|
|
|
|
poll_fd = fdarray;
|
|
|
|
while (waiting && nfds--) {
|
|
|
|
if (!poll_fd->events)
|
|
goto skip2;
|
|
|
|
if (poll_fd->fd <= 0) {
|
|
poll_fd->revents = POLLNVAL;
|
|
goto skip2;
|
|
}
|
|
|
|
if (FD_ISSET(poll_fd->fd, &readfds)) {
|
|
|
|
/* defer POLLHUP / error detect to false read attempt */
|
|
|
|
poll_fd->revents |= POLLIN;
|
|
waiting--;
|
|
}
|
|
|
|
if (FD_ISSET(poll_fd->fd, &writefds)) {
|
|
|
|
poll_fd->revents |= poll_fd->events & POLLOUT;
|
|
waiting--;
|
|
}
|
|
|
|
if (poll_fd->revents)
|
|
pending++;
|
|
|
|
skip2:
|
|
poll_fd++;
|
|
}
|
|
|
|
return pending;
|
|
}
|