diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 5376ea13..50aeaee2 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -2501,6 +2501,7 @@ libwebsocket_create_context(int port, const char *interf, WORD wVersionRequested; WSADATA wsaData; int err; + HMODULE wsdll; /* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */ wVersionRequested = MAKEWORD(2, 2); @@ -2513,6 +2514,17 @@ libwebsocket_create_context(int port, const char *interf, err); return NULL; } + + wsdll = GetModuleHandle("Ws2_32.dll"); + if (wsdll) + { + poll = (PFNWSAPOLL)GetProcAddress(wsdll, "WSAPoll"); + } + + if (!poll) + { + poll = emulated_poll; + } } #endif diff --git a/win32port/libwebsocketswin32/libwebsocketswin32.vcxproj b/win32port/libwebsocketswin32/libwebsocketswin32.vcxproj index 14d4b0bf..8c371f3f 100644 --- a/win32port/libwebsocketswin32/libwebsocketswin32.vcxproj +++ b/win32port/libwebsocketswin32/libwebsocketswin32.vcxproj @@ -243,6 +243,7 @@ Ws2_32.lib;..\..\output\ZLib_vc100-mt-s.lib;%(AdditionalDependencies) true true + true @@ -257,6 +258,7 @@ + @@ -264,6 +266,7 @@ + diff --git a/win32port/libwebsocketswin32/libwebsocketswin32.vcxproj.filters b/win32port/libwebsocketswin32/libwebsocketswin32.vcxproj.filters index 878f16a4..3c6edbb3 100644 --- a/win32port/libwebsocketswin32/libwebsocketswin32.vcxproj.filters +++ b/win32port/libwebsocketswin32/libwebsocketswin32.vcxproj.filters @@ -45,6 +45,9 @@ Source Files + + Source Files + @@ -62,5 +65,8 @@ Source Files + + Header Files + \ No newline at end of file diff --git a/win32port/win32helpers/websock-w32.c b/win32port/win32helpers/websock-w32.c new file mode 100644 index 00000000..b6b339a0 --- /dev/null +++ b/win32port/win32helpers/websock-w32.c @@ -0,0 +1,156 @@ +#define FD_SETSIZE 256 + +#include +#include +#include +#include "websock-w32.h" + + +PFNWSAPOLL poll = NULL; + + +INT WSAAPI emulated_poll(LPWSAPOLLFD fdarray, ULONG nfds, INT timeout) +{ + fd_set readfds, writefds; + struct timeval tv, *ptv; + SOCKET max_socket; + ULONG n; + int num_bits, num_sockets_ready; + + if (NULL == fdarray) + { + errno = EFAULT; + return -1; + } + + FD_ZERO(&readfds); + FD_ZERO(&writefds); + + max_socket = 0; + n = 0; + while (n < nfds) + { + WSAPOLLFD * const poll_fd = (fdarray + n); + SOCKET sock = poll_fd->fd; + poll_fd->revents = 0; + if (0 <= sock) + { + const SHORT events = poll_fd->events; + if (events) + { + if (max_socket < sock) + { + max_socket = sock; + } + + if (events & POLLIN) + { + FD_SET(sock, &readfds); + } + + if (events & POLLOUT) + { + FD_SET(sock, &writefds); + } + } + } + n++; + } + + if (0 > timeout) + { + ptv = NULL; + } + else + { + ptv = &tv; + if (0 == timeout) + { + tv.tv_sec = 0; + tv.tv_usec = 0; + } + else if (1000 <= timeout) + { + tv.tv_sec = (timeout / 1000); + tv.tv_usec = ((timeout % 1000) * 1000); + } + else + { + tv.tv_sec = 0; + tv.tv_usec = (timeout * 1000); + } + } + + num_bits = select((int)max_socket + 1, &readfds, &writefds, NULL, ptv); + if (0 >= num_bits) + { + return num_bits; + } + + num_sockets_ready = 0; + n = 0; + do + { + WSAPOLLFD * const poll_fd = (fdarray + n); + SOCKET sock = poll_fd->fd; + if (0 <= sock) + { + const SHORT events = poll_fd->events; + if (events) + { + if (FD_ISSET(sock, &readfds)) + { + const int saved_error = WSAGetLastError(); + char test_data[4] = {0}; + int ret; + + /* support for POLLHUP */ + ret = recv(poll_fd->fd, test_data, sizeof(test_data), MSG_PEEK); + if (SOCKET_ERROR == ret) + { + const int err = WSAGetLastError(); + if (err == WSAESHUTDOWN || err == WSAECONNRESET || + err == WSAECONNABORTED || err == WSAENETRESET) + { + poll_fd->revents |= POLLHUP; + } + } + else + { + if (events & POLLIN) + { + poll_fd->revents |= POLLIN; + } + } + + WSASetLastError(saved_error); + + --num_bits; + } + + if (FD_ISSET(sock, &writefds)) + { + if (events & POLLOUT) + { + poll_fd->revents |= POLLOUT; + } + + --num_bits; + } + + if (poll_fd->revents) + { + num_sockets_ready++; + } + } + } + else + { + poll_fd->revents = POLLNVAL; + } + n++; + } + while (0 < num_bits && n < nfds); + + return num_sockets_ready; +} diff --git a/win32port/win32helpers/websock-w32.h b/win32port/win32helpers/websock-w32.h index efde5ed3..5d64dfd8 100644 --- a/win32port/win32helpers/websock-w32.h +++ b/win32port/win32helpers/websock-w32.h @@ -18,7 +18,11 @@ #define random rand #define usleep _sleep -#define poll WSAPoll + +typedef INT (WSAAPI *PFNWSAPOLL)(LPWSAPOLLFD fdarray, ULONG nfds, INT timeout); +extern PFNWSAPOLL poll; + +extern INT WSAAPI emulated_poll(LPWSAPOLLFD fdarray, ULONG nfds, INT timeout); /* override configure because we are not using Makefiles */