1*663afb9bSAndroid Build Coastguard Worker /*
2*663afb9bSAndroid Build Coastguard Worker * Copyright (c) 2009-2012 Niels Provos, Nick Mathewson
3*663afb9bSAndroid Build Coastguard Worker *
4*663afb9bSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
5*663afb9bSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
6*663afb9bSAndroid Build Coastguard Worker * are met:
7*663afb9bSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*663afb9bSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*663afb9bSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*663afb9bSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*663afb9bSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*663afb9bSAndroid Build Coastguard Worker * 3. The name of the author may not be used to endorse or promote products
13*663afb9bSAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
14*663afb9bSAndroid Build Coastguard Worker *
15*663afb9bSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16*663afb9bSAndroid Build Coastguard Worker * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17*663afb9bSAndroid Build Coastguard Worker * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18*663afb9bSAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19*663afb9bSAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20*663afb9bSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21*663afb9bSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22*663afb9bSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*663afb9bSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24*663afb9bSAndroid Build Coastguard Worker * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*663afb9bSAndroid Build Coastguard Worker */
26*663afb9bSAndroid Build Coastguard Worker #include "evconfig-private.h"
27*663afb9bSAndroid Build Coastguard Worker
28*663afb9bSAndroid Build Coastguard Worker #ifndef _WIN32_WINNT
29*663afb9bSAndroid Build Coastguard Worker /* Minimum required for InitializeCriticalSectionAndSpinCount */
30*663afb9bSAndroid Build Coastguard Worker #define _WIN32_WINNT 0x0403
31*663afb9bSAndroid Build Coastguard Worker #endif
32*663afb9bSAndroid Build Coastguard Worker #include <winsock2.h>
33*663afb9bSAndroid Build Coastguard Worker #include <windows.h>
34*663afb9bSAndroid Build Coastguard Worker #include <process.h>
35*663afb9bSAndroid Build Coastguard Worker #include <stdio.h>
36*663afb9bSAndroid Build Coastguard Worker #include <mswsock.h>
37*663afb9bSAndroid Build Coastguard Worker
38*663afb9bSAndroid Build Coastguard Worker #include "event2/util.h"
39*663afb9bSAndroid Build Coastguard Worker #include "util-internal.h"
40*663afb9bSAndroid Build Coastguard Worker #include "iocp-internal.h"
41*663afb9bSAndroid Build Coastguard Worker #include "log-internal.h"
42*663afb9bSAndroid Build Coastguard Worker #include "mm-internal.h"
43*663afb9bSAndroid Build Coastguard Worker #include "event-internal.h"
44*663afb9bSAndroid Build Coastguard Worker #include "evthread-internal.h"
45*663afb9bSAndroid Build Coastguard Worker
46*663afb9bSAndroid Build Coastguard Worker #define NOTIFICATION_KEY ((ULONG_PTR)-1)
47*663afb9bSAndroid Build Coastguard Worker
48*663afb9bSAndroid Build Coastguard Worker void
event_overlapped_init_(struct event_overlapped * o,iocp_callback cb)49*663afb9bSAndroid Build Coastguard Worker event_overlapped_init_(struct event_overlapped *o, iocp_callback cb)
50*663afb9bSAndroid Build Coastguard Worker {
51*663afb9bSAndroid Build Coastguard Worker memset(o, 0, sizeof(struct event_overlapped));
52*663afb9bSAndroid Build Coastguard Worker o->cb = cb;
53*663afb9bSAndroid Build Coastguard Worker }
54*663afb9bSAndroid Build Coastguard Worker
55*663afb9bSAndroid Build Coastguard Worker static void
handle_entry(OVERLAPPED * o,ULONG_PTR completion_key,DWORD nBytes,int ok)56*663afb9bSAndroid Build Coastguard Worker handle_entry(OVERLAPPED *o, ULONG_PTR completion_key, DWORD nBytes, int ok)
57*663afb9bSAndroid Build Coastguard Worker {
58*663afb9bSAndroid Build Coastguard Worker struct event_overlapped *eo =
59*663afb9bSAndroid Build Coastguard Worker EVUTIL_UPCAST(o, struct event_overlapped, overlapped);
60*663afb9bSAndroid Build Coastguard Worker eo->cb(eo, completion_key, nBytes, ok);
61*663afb9bSAndroid Build Coastguard Worker }
62*663afb9bSAndroid Build Coastguard Worker
63*663afb9bSAndroid Build Coastguard Worker static void
loop(void * port_)64*663afb9bSAndroid Build Coastguard Worker loop(void *port_)
65*663afb9bSAndroid Build Coastguard Worker {
66*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port *port = port_;
67*663afb9bSAndroid Build Coastguard Worker long ms = port->ms;
68*663afb9bSAndroid Build Coastguard Worker HANDLE p = port->port;
69*663afb9bSAndroid Build Coastguard Worker
70*663afb9bSAndroid Build Coastguard Worker if (ms <= 0)
71*663afb9bSAndroid Build Coastguard Worker ms = INFINITE;
72*663afb9bSAndroid Build Coastguard Worker
73*663afb9bSAndroid Build Coastguard Worker while (1) {
74*663afb9bSAndroid Build Coastguard Worker OVERLAPPED *overlapped=NULL;
75*663afb9bSAndroid Build Coastguard Worker ULONG_PTR key=0;
76*663afb9bSAndroid Build Coastguard Worker DWORD bytes=0;
77*663afb9bSAndroid Build Coastguard Worker int ok = GetQueuedCompletionStatus(p, &bytes, &key,
78*663afb9bSAndroid Build Coastguard Worker &overlapped, ms);
79*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(&port->lock);
80*663afb9bSAndroid Build Coastguard Worker if (port->shutdown) {
81*663afb9bSAndroid Build Coastguard Worker if (--port->n_live_threads == 0)
82*663afb9bSAndroid Build Coastguard Worker ReleaseSemaphore(port->shutdownSemaphore, 1,
83*663afb9bSAndroid Build Coastguard Worker NULL);
84*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&port->lock);
85*663afb9bSAndroid Build Coastguard Worker return;
86*663afb9bSAndroid Build Coastguard Worker }
87*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&port->lock);
88*663afb9bSAndroid Build Coastguard Worker
89*663afb9bSAndroid Build Coastguard Worker if (key != NOTIFICATION_KEY && overlapped)
90*663afb9bSAndroid Build Coastguard Worker handle_entry(overlapped, key, bytes, ok);
91*663afb9bSAndroid Build Coastguard Worker else if (!overlapped)
92*663afb9bSAndroid Build Coastguard Worker break;
93*663afb9bSAndroid Build Coastguard Worker }
94*663afb9bSAndroid Build Coastguard Worker event_warnx("GetQueuedCompletionStatus exited with no event.");
95*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(&port->lock);
96*663afb9bSAndroid Build Coastguard Worker if (--port->n_live_threads == 0)
97*663afb9bSAndroid Build Coastguard Worker ReleaseSemaphore(port->shutdownSemaphore, 1, NULL);
98*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&port->lock);
99*663afb9bSAndroid Build Coastguard Worker }
100*663afb9bSAndroid Build Coastguard Worker
101*663afb9bSAndroid Build Coastguard Worker int
event_iocp_port_associate_(struct event_iocp_port * port,evutil_socket_t fd,ev_uintptr_t key)102*663afb9bSAndroid Build Coastguard Worker event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd,
103*663afb9bSAndroid Build Coastguard Worker ev_uintptr_t key)
104*663afb9bSAndroid Build Coastguard Worker {
105*663afb9bSAndroid Build Coastguard Worker HANDLE h;
106*663afb9bSAndroid Build Coastguard Worker h = CreateIoCompletionPort((HANDLE)fd, port->port, key, port->n_threads);
107*663afb9bSAndroid Build Coastguard Worker if (!h)
108*663afb9bSAndroid Build Coastguard Worker return -1;
109*663afb9bSAndroid Build Coastguard Worker return 0;
110*663afb9bSAndroid Build Coastguard Worker }
111*663afb9bSAndroid Build Coastguard Worker
112*663afb9bSAndroid Build Coastguard Worker static void *
get_extension_function(SOCKET s,const GUID * which_fn)113*663afb9bSAndroid Build Coastguard Worker get_extension_function(SOCKET s, const GUID *which_fn)
114*663afb9bSAndroid Build Coastguard Worker {
115*663afb9bSAndroid Build Coastguard Worker void *ptr = NULL;
116*663afb9bSAndroid Build Coastguard Worker DWORD bytes=0;
117*663afb9bSAndroid Build Coastguard Worker WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
118*663afb9bSAndroid Build Coastguard Worker (GUID*)which_fn, sizeof(*which_fn),
119*663afb9bSAndroid Build Coastguard Worker &ptr, sizeof(ptr),
120*663afb9bSAndroid Build Coastguard Worker &bytes, NULL, NULL);
121*663afb9bSAndroid Build Coastguard Worker
122*663afb9bSAndroid Build Coastguard Worker /* No need to detect errors here: if ptr is set, then we have a good
123*663afb9bSAndroid Build Coastguard Worker function pointer. Otherwise, we should behave as if we had no
124*663afb9bSAndroid Build Coastguard Worker function pointer.
125*663afb9bSAndroid Build Coastguard Worker */
126*663afb9bSAndroid Build Coastguard Worker return ptr;
127*663afb9bSAndroid Build Coastguard Worker }
128*663afb9bSAndroid Build Coastguard Worker
129*663afb9bSAndroid Build Coastguard Worker /* Mingw doesn't have these in its mswsock.h. The values are copied from
130*663afb9bSAndroid Build Coastguard Worker wine.h. Perhaps if we copy them exactly, the cargo will come again.
131*663afb9bSAndroid Build Coastguard Worker */
132*663afb9bSAndroid Build Coastguard Worker #ifndef WSAID_ACCEPTEX
133*663afb9bSAndroid Build Coastguard Worker #define WSAID_ACCEPTEX \
134*663afb9bSAndroid Build Coastguard Worker {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
135*663afb9bSAndroid Build Coastguard Worker #endif
136*663afb9bSAndroid Build Coastguard Worker #ifndef WSAID_CONNECTEX
137*663afb9bSAndroid Build Coastguard Worker #define WSAID_CONNECTEX \
138*663afb9bSAndroid Build Coastguard Worker {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
139*663afb9bSAndroid Build Coastguard Worker #endif
140*663afb9bSAndroid Build Coastguard Worker #ifndef WSAID_GETACCEPTEXSOCKADDRS
141*663afb9bSAndroid Build Coastguard Worker #define WSAID_GETACCEPTEXSOCKADDRS \
142*663afb9bSAndroid Build Coastguard Worker {0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
143*663afb9bSAndroid Build Coastguard Worker #endif
144*663afb9bSAndroid Build Coastguard Worker
145*663afb9bSAndroid Build Coastguard Worker static int extension_fns_initialized = 0;
146*663afb9bSAndroid Build Coastguard Worker
147*663afb9bSAndroid Build Coastguard Worker static void
init_extension_functions(struct win32_extension_fns * ext)148*663afb9bSAndroid Build Coastguard Worker init_extension_functions(struct win32_extension_fns *ext)
149*663afb9bSAndroid Build Coastguard Worker {
150*663afb9bSAndroid Build Coastguard Worker const GUID acceptex = WSAID_ACCEPTEX;
151*663afb9bSAndroid Build Coastguard Worker const GUID connectex = WSAID_CONNECTEX;
152*663afb9bSAndroid Build Coastguard Worker const GUID getacceptexsockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
153*663afb9bSAndroid Build Coastguard Worker SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
154*663afb9bSAndroid Build Coastguard Worker if (s == EVUTIL_INVALID_SOCKET)
155*663afb9bSAndroid Build Coastguard Worker return;
156*663afb9bSAndroid Build Coastguard Worker ext->AcceptEx = get_extension_function(s, &acceptex);
157*663afb9bSAndroid Build Coastguard Worker ext->ConnectEx = get_extension_function(s, &connectex);
158*663afb9bSAndroid Build Coastguard Worker ext->GetAcceptExSockaddrs = get_extension_function(s,
159*663afb9bSAndroid Build Coastguard Worker &getacceptexsockaddrs);
160*663afb9bSAndroid Build Coastguard Worker closesocket(s);
161*663afb9bSAndroid Build Coastguard Worker
162*663afb9bSAndroid Build Coastguard Worker extension_fns_initialized = 1;
163*663afb9bSAndroid Build Coastguard Worker }
164*663afb9bSAndroid Build Coastguard Worker
165*663afb9bSAndroid Build Coastguard Worker static struct win32_extension_fns the_extension_fns;
166*663afb9bSAndroid Build Coastguard Worker
167*663afb9bSAndroid Build Coastguard Worker const struct win32_extension_fns *
event_get_win32_extension_fns_(void)168*663afb9bSAndroid Build Coastguard Worker event_get_win32_extension_fns_(void)
169*663afb9bSAndroid Build Coastguard Worker {
170*663afb9bSAndroid Build Coastguard Worker return &the_extension_fns;
171*663afb9bSAndroid Build Coastguard Worker }
172*663afb9bSAndroid Build Coastguard Worker
173*663afb9bSAndroid Build Coastguard Worker #define N_CPUS_DEFAULT 2
174*663afb9bSAndroid Build Coastguard Worker
175*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port *
event_iocp_port_launch_(int n_cpus)176*663afb9bSAndroid Build Coastguard Worker event_iocp_port_launch_(int n_cpus)
177*663afb9bSAndroid Build Coastguard Worker {
178*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port *port;
179*663afb9bSAndroid Build Coastguard Worker int i;
180*663afb9bSAndroid Build Coastguard Worker
181*663afb9bSAndroid Build Coastguard Worker if (!extension_fns_initialized)
182*663afb9bSAndroid Build Coastguard Worker init_extension_functions(&the_extension_fns);
183*663afb9bSAndroid Build Coastguard Worker
184*663afb9bSAndroid Build Coastguard Worker if (!(port = mm_calloc(1, sizeof(struct event_iocp_port))))
185*663afb9bSAndroid Build Coastguard Worker return NULL;
186*663afb9bSAndroid Build Coastguard Worker
187*663afb9bSAndroid Build Coastguard Worker if (n_cpus <= 0)
188*663afb9bSAndroid Build Coastguard Worker n_cpus = N_CPUS_DEFAULT;
189*663afb9bSAndroid Build Coastguard Worker port->n_threads = n_cpus * 2;
190*663afb9bSAndroid Build Coastguard Worker port->threads = mm_calloc(port->n_threads, sizeof(HANDLE));
191*663afb9bSAndroid Build Coastguard Worker if (!port->threads)
192*663afb9bSAndroid Build Coastguard Worker goto err;
193*663afb9bSAndroid Build Coastguard Worker
194*663afb9bSAndroid Build Coastguard Worker port->port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
195*663afb9bSAndroid Build Coastguard Worker n_cpus);
196*663afb9bSAndroid Build Coastguard Worker port->ms = -1;
197*663afb9bSAndroid Build Coastguard Worker if (!port->port)
198*663afb9bSAndroid Build Coastguard Worker goto err;
199*663afb9bSAndroid Build Coastguard Worker
200*663afb9bSAndroid Build Coastguard Worker port->shutdownSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
201*663afb9bSAndroid Build Coastguard Worker if (!port->shutdownSemaphore)
202*663afb9bSAndroid Build Coastguard Worker goto err;
203*663afb9bSAndroid Build Coastguard Worker
204*663afb9bSAndroid Build Coastguard Worker for (i=0; i<port->n_threads; ++i) {
205*663afb9bSAndroid Build Coastguard Worker ev_uintptr_t th = _beginthread(loop, 0, port);
206*663afb9bSAndroid Build Coastguard Worker if (th == (ev_uintptr_t)-1)
207*663afb9bSAndroid Build Coastguard Worker goto err;
208*663afb9bSAndroid Build Coastguard Worker port->threads[i] = (HANDLE)th;
209*663afb9bSAndroid Build Coastguard Worker ++port->n_live_threads;
210*663afb9bSAndroid Build Coastguard Worker }
211*663afb9bSAndroid Build Coastguard Worker
212*663afb9bSAndroid Build Coastguard Worker InitializeCriticalSectionAndSpinCount(&port->lock, 1000);
213*663afb9bSAndroid Build Coastguard Worker
214*663afb9bSAndroid Build Coastguard Worker return port;
215*663afb9bSAndroid Build Coastguard Worker err:
216*663afb9bSAndroid Build Coastguard Worker if (port->port)
217*663afb9bSAndroid Build Coastguard Worker CloseHandle(port->port);
218*663afb9bSAndroid Build Coastguard Worker if (port->threads)
219*663afb9bSAndroid Build Coastguard Worker mm_free(port->threads);
220*663afb9bSAndroid Build Coastguard Worker if (port->shutdownSemaphore)
221*663afb9bSAndroid Build Coastguard Worker CloseHandle(port->shutdownSemaphore);
222*663afb9bSAndroid Build Coastguard Worker mm_free(port);
223*663afb9bSAndroid Build Coastguard Worker return NULL;
224*663afb9bSAndroid Build Coastguard Worker }
225*663afb9bSAndroid Build Coastguard Worker
226*663afb9bSAndroid Build Coastguard Worker static void
event_iocp_port_unlock_and_free_(struct event_iocp_port * port)227*663afb9bSAndroid Build Coastguard Worker event_iocp_port_unlock_and_free_(struct event_iocp_port *port)
228*663afb9bSAndroid Build Coastguard Worker {
229*663afb9bSAndroid Build Coastguard Worker DeleteCriticalSection(&port->lock);
230*663afb9bSAndroid Build Coastguard Worker CloseHandle(port->port);
231*663afb9bSAndroid Build Coastguard Worker CloseHandle(port->shutdownSemaphore);
232*663afb9bSAndroid Build Coastguard Worker mm_free(port->threads);
233*663afb9bSAndroid Build Coastguard Worker mm_free(port);
234*663afb9bSAndroid Build Coastguard Worker }
235*663afb9bSAndroid Build Coastguard Worker
236*663afb9bSAndroid Build Coastguard Worker static int
event_iocp_notify_all(struct event_iocp_port * port)237*663afb9bSAndroid Build Coastguard Worker event_iocp_notify_all(struct event_iocp_port *port)
238*663afb9bSAndroid Build Coastguard Worker {
239*663afb9bSAndroid Build Coastguard Worker int i, r, ok=1;
240*663afb9bSAndroid Build Coastguard Worker for (i=0; i<port->n_threads; ++i) {
241*663afb9bSAndroid Build Coastguard Worker r = PostQueuedCompletionStatus(port->port, 0, NOTIFICATION_KEY,
242*663afb9bSAndroid Build Coastguard Worker NULL);
243*663afb9bSAndroid Build Coastguard Worker if (!r)
244*663afb9bSAndroid Build Coastguard Worker ok = 0;
245*663afb9bSAndroid Build Coastguard Worker }
246*663afb9bSAndroid Build Coastguard Worker return ok ? 0 : -1;
247*663afb9bSAndroid Build Coastguard Worker }
248*663afb9bSAndroid Build Coastguard Worker
249*663afb9bSAndroid Build Coastguard Worker int
event_iocp_shutdown_(struct event_iocp_port * port,long waitMsec)250*663afb9bSAndroid Build Coastguard Worker event_iocp_shutdown_(struct event_iocp_port *port, long waitMsec)
251*663afb9bSAndroid Build Coastguard Worker {
252*663afb9bSAndroid Build Coastguard Worker DWORD ms = INFINITE;
253*663afb9bSAndroid Build Coastguard Worker int n;
254*663afb9bSAndroid Build Coastguard Worker
255*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(&port->lock);
256*663afb9bSAndroid Build Coastguard Worker port->shutdown = 1;
257*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&port->lock);
258*663afb9bSAndroid Build Coastguard Worker event_iocp_notify_all(port);
259*663afb9bSAndroid Build Coastguard Worker
260*663afb9bSAndroid Build Coastguard Worker if (waitMsec >= 0)
261*663afb9bSAndroid Build Coastguard Worker ms = waitMsec;
262*663afb9bSAndroid Build Coastguard Worker
263*663afb9bSAndroid Build Coastguard Worker WaitForSingleObject(port->shutdownSemaphore, ms);
264*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(&port->lock);
265*663afb9bSAndroid Build Coastguard Worker n = port->n_live_threads;
266*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&port->lock);
267*663afb9bSAndroid Build Coastguard Worker if (n == 0) {
268*663afb9bSAndroid Build Coastguard Worker event_iocp_port_unlock_and_free_(port);
269*663afb9bSAndroid Build Coastguard Worker return 0;
270*663afb9bSAndroid Build Coastguard Worker } else {
271*663afb9bSAndroid Build Coastguard Worker return -1;
272*663afb9bSAndroid Build Coastguard Worker }
273*663afb9bSAndroid Build Coastguard Worker }
274*663afb9bSAndroid Build Coastguard Worker
275*663afb9bSAndroid Build Coastguard Worker int
event_iocp_activate_overlapped_(struct event_iocp_port * port,struct event_overlapped * o,ev_uintptr_t key,ev_uint32_t n)276*663afb9bSAndroid Build Coastguard Worker event_iocp_activate_overlapped_(
277*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port *port, struct event_overlapped *o,
278*663afb9bSAndroid Build Coastguard Worker ev_uintptr_t key, ev_uint32_t n)
279*663afb9bSAndroid Build Coastguard Worker {
280*663afb9bSAndroid Build Coastguard Worker BOOL r;
281*663afb9bSAndroid Build Coastguard Worker
282*663afb9bSAndroid Build Coastguard Worker r = PostQueuedCompletionStatus(port->port, n, key, &o->overlapped);
283*663afb9bSAndroid Build Coastguard Worker return (r==0) ? -1 : 0;
284*663afb9bSAndroid Build Coastguard Worker }
285*663afb9bSAndroid Build Coastguard Worker
286*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port *
event_base_get_iocp_(struct event_base * base)287*663afb9bSAndroid Build Coastguard Worker event_base_get_iocp_(struct event_base *base)
288*663afb9bSAndroid Build Coastguard Worker {
289*663afb9bSAndroid Build Coastguard Worker #ifdef _WIN32
290*663afb9bSAndroid Build Coastguard Worker return base->iocp;
291*663afb9bSAndroid Build Coastguard Worker #else
292*663afb9bSAndroid Build Coastguard Worker return NULL;
293*663afb9bSAndroid Build Coastguard Worker #endif
294*663afb9bSAndroid Build Coastguard Worker }
295