diff options
author | Nick Mathewson <nickm@torproject.org> | 2009-10-29 18:30:43 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2009-10-29 18:30:43 +0000 |
commit | fa313f28c57769a819c8d4194180571c6772acf8 (patch) | |
tree | b5516547d591fe09e860bcf5ba5dd7466fa13e7f | |
parent | 9976f1e74c1a285a591d8a80af61727af50b4961 (diff) | |
download | libevent-fa313f28c57769a819c8d4194180571c6772acf8.tar.gz |
Extract XP-only functions when initializing the IOCP port
svn:r1479
-rw-r--r-- | event_iocp.c | 62 | ||||
-rw-r--r-- | iocp-internal.h | 19 |
2 files changed, 80 insertions, 1 deletions
diff --git a/event_iocp.c b/event_iocp.c index 4c144af6..b4350ef6 100644 --- a/event_iocp.c +++ b/event_iocp.c @@ -28,6 +28,7 @@ #include <windows.h> #include <process.h> #include <stdio.h> +#include <mswsock.h> #include "event2/util.h" #include "util-internal.h" @@ -98,12 +99,73 @@ event_iocp_port_associate(struct event_iocp_port *port, evutil_socket_t fd, return 0; } +static void * +get_extension_function(SOCKET s, const GUID *which_fn) +{ + void *ptr = NULL; + DWORD bytes=0; + WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, + (GUID*)which_fn, sizeof(*which_fn), + &ptr, sizeof(ptr), + &bytes, 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; +} + +/* Mingw doesn't have these in its mswsock.h. The values are copied from + wine.h. Perhaps if we copy them exactly, the cargo will come again. +*/ +#ifndef WSAID_ACCEPTEX +#define WSAID_ACCEPTEX \ + {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}} +#endif +#ifndef WSAID_CONNECTEX +#define WSAID_CONNECTEX \ + {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}} +#endif +#ifndef WSAID_GETACCEPTEXSOCKADDRS +#define WSAID_GETACCEPTEXSOCKADDRS \ + {0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}} +#endif + +static void +init_extension_functions(struct win32_extension_fns *ext) +{ + const GUID acceptex = WSAID_ACCEPTEX; + const GUID connectex = WSAID_CONNECTEX; + const GUID getacceptexsockaddrs = WSAID_GETACCEPTEXSOCKADDRS; + SOCKET s = socket(AF_INET, SOCK_STREAM, 0); + if (s == INVALID_SOCKET) + return; + ext->AcceptEx = get_extension_function(s, &acceptex); + ext->ConnectEx = get_extension_function(s, &connectex); + ext->GetAcceptExSockaddrs = get_extension_function(s, + &getacceptexsockaddrs); + closesocket(s); +} + +static struct win32_extension_fns the_extension_fns; +static int extension_fns_initialized = 0; + +const struct win32_extension_fns * +event_get_win32_extension_fns(void) +{ + return &the_extension_fns; +} + struct event_iocp_port * event_iocp_port_launch(void) { struct event_iocp_port *port; int i; + if (!extension_fns_initialized) + init_extension_functions(&the_extension_fns); + if (!(port = mm_calloc(1, sizeof(struct event_iocp_port)))) return NULL; port->n_threads = 2; diff --git a/iocp-internal.h b/iocp-internal.h index d743bd54..31024cc1 100644 --- a/iocp-internal.h +++ b/iocp-internal.h @@ -53,6 +53,21 @@ struct event_overlapped { iocp_callback cb; }; +/* Mingw's headers don't define LPFN_ACCEPTEX. */ + +typedef BOOL (WINAPI *AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const struct sockaddr *, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED); +typedef void (WINAPI *GetAcceptExSockaddrsPtr)(PVOID, DWORD, DWORD, DWORD, LPSOCKADDR *, LPINT, LPSOCKADDR *, LPINT); + +/** Internal use only. Holds pointers to functions that only some versions of + Windows provide. + */ +struct win32_extension_fns { + AcceptExPtr AcceptEx; + ConnectExPtr ConnectEx; + GetAcceptExSockaddrsPtr GetAcceptExSockaddrs; +}; + /** Internal use only. Stores a Windows IO Completion port, along with related data. @@ -73,9 +88,11 @@ 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; }; + +const struct win32_extension_fns *event_get_win32_extension_fns(void); #else /* Dummy definition so we can test-compile more things on unix. */ struct event_overlapped { |