diff --git a/libevent/event_iocp.c b/libevent/event_iocp.c index 4c144af..0e0586e 100644 --- a/libevent/event_iocp.c +++ b/libevent/event_iocp.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "event2/util.h" #include "util-internal.h" @@ -98,6 +99,34 @@ event_iocp_port_associate(struct event_iocp_port *port, evutil_socket_t fd, return 0; } +static void * +get_extention_function(SOCKET s, GUID which_fn) +{ + void *ptr = NULL; + DWORD bytes; + WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINER, + &which_fn, sizeof(which_fn), + &ptr, sizeof(ptr), + NULL, NULL); + + /* No need to detect errors here: if ptr is set, then we have a good + function pointer. Otherwise, we should behave as if we had no + function pointer. + */ + return ptr; +} + +static void +init_extension_functions(struct win32_extension_fns *ext) +{ + SOCKET s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return; + ext->AcceptEx = get_extension_function(s, WSAID_ACCEPTEX); + ext->ConnectEx = get_extension_function(s, WSAID_CONNECTEX); + closesocket(s); +} + struct event_iocp_port * event_iocp_port_launch(void) { @@ -130,6 +159,8 @@ event_iocp_port_launch(void) InitializeCriticalSection(&port->lock); + init_extension_functions(&port->ext); + return port; err: if (port->port) diff --git a/libevent/iocp-internal.h b/libevent/iocp-internal.h index d743bd5..414066a 100644 --- a/libevent/iocp-internal.h +++ b/libevent/iocp-internal.h @@ -53,6 +53,14 @@ struct event_overlapped { iocp_callback cb; }; +/** Internal use only. Holds pointers to functions that only some versions of + Windows provide. + */ +struct win32_extention_fns { + LPFN_ACCEPTEX AcceptEx; + LPFN_CONNECTEX ConnectEx; +}; + /** Internal use only. Stores a Windows IO Completion port, along with related data. @@ -73,8 +81,10 @@ struct event_iocp_port { HANDLE *threads; /** Number of threads currently open on this port. */ short n_live_threads; - /* A semaphore to signal when we are done shutting down. */ + /** A semaphore to signal when we are done shutting down. */ HANDLE *shutdownSemaphore; + /** Function pointers that only some versions of windows provide. */ + struct win32_extension_fns ext; }; #else /* Dummy definition so we can test-compile more things on unix. */