summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-10-29 18:30:43 +0000
committerNick Mathewson <nickm@torproject.org>2009-10-29 18:30:43 +0000
commitfa313f28c57769a819c8d4194180571c6772acf8 (patch)
treeb5516547d591fe09e860bcf5ba5dd7466fa13e7f
parent9976f1e74c1a285a591d8a80af61727af50b4961 (diff)
downloadlibevent-fa313f28c57769a819c8d4194180571c6772acf8.tar.gz
Extract XP-only functions when initializing the IOCP port
svn:r1479
-rw-r--r--event_iocp.c62
-rw-r--r--iocp-internal.h19
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 {