mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-19 09:15:34 -04:00
Extract XP-only functions when initializing the IOCP port
svn:r1479
This commit is contained in:
parent
9976f1e74c
commit
fa313f28c5
62
event_iocp.c
62
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;
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user