Extract XP-only functions when initializing the IOCP port

svn:r1479
This commit is contained in:
Nick Mathewson 2009-10-29 18:30:43 +00:00
parent 9976f1e74c
commit fa313f28c5
2 changed files with 80 additions and 1 deletions

View File

@ -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;

View File

@ -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 {