1*663afb9bSAndroid Build Coastguard Worker /* 2*663afb9bSAndroid Build Coastguard Worker * Copyright (c) 2009-2012 Niels Provos and 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 27*663afb9bSAndroid Build Coastguard Worker #ifndef IOCP_INTERNAL_H_INCLUDED_ 28*663afb9bSAndroid Build Coastguard Worker #define IOCP_INTERNAL_H_INCLUDED_ 29*663afb9bSAndroid Build Coastguard Worker 30*663afb9bSAndroid Build Coastguard Worker #ifdef __cplusplus 31*663afb9bSAndroid Build Coastguard Worker extern "C" { 32*663afb9bSAndroid Build Coastguard Worker #endif 33*663afb9bSAndroid Build Coastguard Worker 34*663afb9bSAndroid Build Coastguard Worker struct event_overlapped; 35*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port; 36*663afb9bSAndroid Build Coastguard Worker struct evbuffer; 37*663afb9bSAndroid Build Coastguard Worker typedef void (*iocp_callback)(struct event_overlapped *, ev_uintptr_t, ev_ssize_t, int success); 38*663afb9bSAndroid Build Coastguard Worker 39*663afb9bSAndroid Build Coastguard Worker /* This whole file is actually win32 only. We wrap the structures in a win32 40*663afb9bSAndroid Build Coastguard Worker * ifdef so that we can test-compile code that uses these interfaces on 41*663afb9bSAndroid Build Coastguard Worker * non-win32 platforms. */ 42*663afb9bSAndroid Build Coastguard Worker #ifdef _WIN32 43*663afb9bSAndroid Build Coastguard Worker 44*663afb9bSAndroid Build Coastguard Worker /** 45*663afb9bSAndroid Build Coastguard Worker Internal use only. Wraps an OVERLAPPED that we're using for libevent 46*663afb9bSAndroid Build Coastguard Worker functionality. Whenever an event_iocp_port gets an event for a given 47*663afb9bSAndroid Build Coastguard Worker OVERLAPPED*, it upcasts the pointer to an event_overlapped, and calls the 48*663afb9bSAndroid Build Coastguard Worker iocp_callback function with the event_overlapped, the iocp key, and the 49*663afb9bSAndroid Build Coastguard Worker number of bytes transferred as arguments. 50*663afb9bSAndroid Build Coastguard Worker */ 51*663afb9bSAndroid Build Coastguard Worker struct event_overlapped { 52*663afb9bSAndroid Build Coastguard Worker OVERLAPPED overlapped; 53*663afb9bSAndroid Build Coastguard Worker iocp_callback cb; 54*663afb9bSAndroid Build Coastguard Worker }; 55*663afb9bSAndroid Build Coastguard Worker 56*663afb9bSAndroid Build Coastguard Worker /* Mingw's headers don't define LPFN_ACCEPTEX. */ 57*663afb9bSAndroid Build Coastguard Worker 58*663afb9bSAndroid Build Coastguard Worker typedef BOOL (WINAPI *AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED); 59*663afb9bSAndroid Build Coastguard Worker typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const struct sockaddr *, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED); 60*663afb9bSAndroid Build Coastguard Worker typedef void (WINAPI *GetAcceptExSockaddrsPtr)(PVOID, DWORD, DWORD, DWORD, LPSOCKADDR *, LPINT, LPSOCKADDR *, LPINT); 61*663afb9bSAndroid Build Coastguard Worker 62*663afb9bSAndroid Build Coastguard Worker /** Internal use only. Holds pointers to functions that only some versions of 63*663afb9bSAndroid Build Coastguard Worker Windows provide. 64*663afb9bSAndroid Build Coastguard Worker */ 65*663afb9bSAndroid Build Coastguard Worker struct win32_extension_fns { 66*663afb9bSAndroid Build Coastguard Worker AcceptExPtr AcceptEx; 67*663afb9bSAndroid Build Coastguard Worker ConnectExPtr ConnectEx; 68*663afb9bSAndroid Build Coastguard Worker GetAcceptExSockaddrsPtr GetAcceptExSockaddrs; 69*663afb9bSAndroid Build Coastguard Worker }; 70*663afb9bSAndroid Build Coastguard Worker 71*663afb9bSAndroid Build Coastguard Worker /** 72*663afb9bSAndroid Build Coastguard Worker Internal use only. Stores a Windows IO Completion port, along with 73*663afb9bSAndroid Build Coastguard Worker related data. 74*663afb9bSAndroid Build Coastguard Worker */ 75*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port { 76*663afb9bSAndroid Build Coastguard Worker /** The port itself */ 77*663afb9bSAndroid Build Coastguard Worker HANDLE port; 78*663afb9bSAndroid Build Coastguard Worker /* A lock to cover internal structures. */ 79*663afb9bSAndroid Build Coastguard Worker CRITICAL_SECTION lock; 80*663afb9bSAndroid Build Coastguard Worker /** Number of threads ever open on the port. */ 81*663afb9bSAndroid Build Coastguard Worker short n_threads; 82*663afb9bSAndroid Build Coastguard Worker /** True iff we're shutting down all the threads on this port */ 83*663afb9bSAndroid Build Coastguard Worker short shutdown; 84*663afb9bSAndroid Build Coastguard Worker /** How often the threads on this port check for shutdown and other 85*663afb9bSAndroid Build Coastguard Worker * conditions */ 86*663afb9bSAndroid Build Coastguard Worker long ms; 87*663afb9bSAndroid Build Coastguard Worker /* The threads that are waiting for events. */ 88*663afb9bSAndroid Build Coastguard Worker HANDLE *threads; 89*663afb9bSAndroid Build Coastguard Worker /** Number of threads currently open on this port. */ 90*663afb9bSAndroid Build Coastguard Worker short n_live_threads; 91*663afb9bSAndroid Build Coastguard Worker /** A semaphore to signal when we are done shutting down. */ 92*663afb9bSAndroid Build Coastguard Worker HANDLE *shutdownSemaphore; 93*663afb9bSAndroid Build Coastguard Worker }; 94*663afb9bSAndroid Build Coastguard Worker 95*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 96*663afb9bSAndroid Build Coastguard Worker const struct win32_extension_fns *event_get_win32_extension_fns_(void); 97*663afb9bSAndroid Build Coastguard Worker #else 98*663afb9bSAndroid Build Coastguard Worker /* Dummy definition so we can test-compile more things on unix. */ 99*663afb9bSAndroid Build Coastguard Worker struct event_overlapped { 100*663afb9bSAndroid Build Coastguard Worker iocp_callback cb; 101*663afb9bSAndroid Build Coastguard Worker }; 102*663afb9bSAndroid Build Coastguard Worker #endif 103*663afb9bSAndroid Build Coastguard Worker 104*663afb9bSAndroid Build Coastguard Worker /** Initialize the fields in an event_overlapped. 105*663afb9bSAndroid Build Coastguard Worker 106*663afb9bSAndroid Build Coastguard Worker @param overlapped The struct event_overlapped to initialize 107*663afb9bSAndroid Build Coastguard Worker @param cb The callback that should be invoked once the IO operation has 108*663afb9bSAndroid Build Coastguard Worker finished. 109*663afb9bSAndroid Build Coastguard Worker */ 110*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 111*663afb9bSAndroid Build Coastguard Worker void event_overlapped_init_(struct event_overlapped *, iocp_callback cb); 112*663afb9bSAndroid Build Coastguard Worker 113*663afb9bSAndroid Build Coastguard Worker /** Allocate and return a new evbuffer that supports overlapped IO on a given 114*663afb9bSAndroid Build Coastguard Worker socket. The socket must be associated with an IO completion port using 115*663afb9bSAndroid Build Coastguard Worker event_iocp_port_associate_. 116*663afb9bSAndroid Build Coastguard Worker */ 117*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 118*663afb9bSAndroid Build Coastguard Worker struct evbuffer *evbuffer_overlapped_new_(evutil_socket_t fd); 119*663afb9bSAndroid Build Coastguard Worker 120*663afb9bSAndroid Build Coastguard Worker /** XXXX Document (nickm) */ 121*663afb9bSAndroid Build Coastguard Worker evutil_socket_t evbuffer_overlapped_get_fd_(struct evbuffer *buf); 122*663afb9bSAndroid Build Coastguard Worker 123*663afb9bSAndroid Build Coastguard Worker void evbuffer_overlapped_set_fd_(struct evbuffer *buf, evutil_socket_t fd); 124*663afb9bSAndroid Build Coastguard Worker 125*663afb9bSAndroid Build Coastguard Worker /** Start reading data onto the end of an overlapped evbuffer. 126*663afb9bSAndroid Build Coastguard Worker 127*663afb9bSAndroid Build Coastguard Worker An evbuffer can only have one read pending at a time. While the read 128*663afb9bSAndroid Build Coastguard Worker is in progress, no other data may be added to the end of the buffer. 129*663afb9bSAndroid Build Coastguard Worker The buffer must be created with event_overlapped_init_(). 130*663afb9bSAndroid Build Coastguard Worker evbuffer_commit_read_() must be called in the completion callback. 131*663afb9bSAndroid Build Coastguard Worker 132*663afb9bSAndroid Build Coastguard Worker @param buf The buffer to read onto 133*663afb9bSAndroid Build Coastguard Worker @param n The number of bytes to try to read. 134*663afb9bSAndroid Build Coastguard Worker @param ol Overlapped object with associated completion callback. 135*663afb9bSAndroid Build Coastguard Worker @return 0 on success, -1 on error. 136*663afb9bSAndroid Build Coastguard Worker */ 137*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 138*663afb9bSAndroid Build Coastguard Worker int evbuffer_launch_read_(struct evbuffer *buf, size_t n, struct event_overlapped *ol); 139*663afb9bSAndroid Build Coastguard Worker 140*663afb9bSAndroid Build Coastguard Worker /** Start writing data from the start of an evbuffer. 141*663afb9bSAndroid Build Coastguard Worker 142*663afb9bSAndroid Build Coastguard Worker An evbuffer can only have one write pending at a time. While the write is 143*663afb9bSAndroid Build Coastguard Worker in progress, no other data may be removed from the front of the buffer. 144*663afb9bSAndroid Build Coastguard Worker The buffer must be created with event_overlapped_init_(). 145*663afb9bSAndroid Build Coastguard Worker evbuffer_commit_write_() must be called in the completion callback. 146*663afb9bSAndroid Build Coastguard Worker 147*663afb9bSAndroid Build Coastguard Worker @param buf The buffer to read onto 148*663afb9bSAndroid Build Coastguard Worker @param n The number of bytes to try to read. 149*663afb9bSAndroid Build Coastguard Worker @param ol Overlapped object with associated completion callback. 150*663afb9bSAndroid Build Coastguard Worker @return 0 on success, -1 on error. 151*663afb9bSAndroid Build Coastguard Worker */ 152*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 153*663afb9bSAndroid Build Coastguard Worker int evbuffer_launch_write_(struct evbuffer *buf, ev_ssize_t n, struct event_overlapped *ol); 154*663afb9bSAndroid Build Coastguard Worker 155*663afb9bSAndroid Build Coastguard Worker /** XXX document */ 156*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 157*663afb9bSAndroid Build Coastguard Worker void evbuffer_commit_read_(struct evbuffer *, ev_ssize_t); 158*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 159*663afb9bSAndroid Build Coastguard Worker void evbuffer_commit_write_(struct evbuffer *, ev_ssize_t); 160*663afb9bSAndroid Build Coastguard Worker 161*663afb9bSAndroid Build Coastguard Worker /** Create an IOCP, and launch its worker threads. Internal use only. 162*663afb9bSAndroid Build Coastguard Worker 163*663afb9bSAndroid Build Coastguard Worker This interface is unstable, and will change. 164*663afb9bSAndroid Build Coastguard Worker */ 165*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 166*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port *event_iocp_port_launch_(int n_cpus); 167*663afb9bSAndroid Build Coastguard Worker 168*663afb9bSAndroid Build Coastguard Worker /** Associate a file descriptor with an iocp, such that overlapped IO on the 169*663afb9bSAndroid Build Coastguard Worker fd will happen on one of the iocp's worker threads. 170*663afb9bSAndroid Build Coastguard Worker */ 171*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 172*663afb9bSAndroid Build Coastguard Worker int event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd, 173*663afb9bSAndroid Build Coastguard Worker ev_uintptr_t key); 174*663afb9bSAndroid Build Coastguard Worker 175*663afb9bSAndroid Build Coastguard Worker /** Tell all threads serving an iocp to stop. Wait for up to waitMsec for all 176*663afb9bSAndroid Build Coastguard Worker the threads to finish whatever they're doing. If waitMsec is -1, wait 177*663afb9bSAndroid Build Coastguard Worker as long as required. If all the threads are done, free the port and return 178*663afb9bSAndroid Build Coastguard Worker 0. Otherwise, return -1. If you get a -1 return value, it is safe to call 179*663afb9bSAndroid Build Coastguard Worker this function again. 180*663afb9bSAndroid Build Coastguard Worker */ 181*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 182*663afb9bSAndroid Build Coastguard Worker int event_iocp_shutdown_(struct event_iocp_port *port, long waitMsec); 183*663afb9bSAndroid Build Coastguard Worker 184*663afb9bSAndroid Build Coastguard Worker /* FIXME document. */ 185*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 186*663afb9bSAndroid Build Coastguard Worker int event_iocp_activate_overlapped_(struct event_iocp_port *port, 187*663afb9bSAndroid Build Coastguard Worker struct event_overlapped *o, 188*663afb9bSAndroid Build Coastguard Worker ev_uintptr_t key, ev_uint32_t n_bytes); 189*663afb9bSAndroid Build Coastguard Worker 190*663afb9bSAndroid Build Coastguard Worker struct event_base; 191*663afb9bSAndroid Build Coastguard Worker /* FIXME document. */ 192*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 193*663afb9bSAndroid Build Coastguard Worker struct event_iocp_port *event_base_get_iocp_(struct event_base *base); 194*663afb9bSAndroid Build Coastguard Worker 195*663afb9bSAndroid Build Coastguard Worker /* FIXME document. */ 196*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 197*663afb9bSAndroid Build Coastguard Worker int event_base_start_iocp_(struct event_base *base, int n_cpus); 198*663afb9bSAndroid Build Coastguard Worker void event_base_stop_iocp_(struct event_base *base); 199*663afb9bSAndroid Build Coastguard Worker 200*663afb9bSAndroid Build Coastguard Worker /* FIXME document. */ 201*663afb9bSAndroid Build Coastguard Worker EVENT2_EXPORT_SYMBOL 202*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bufferevent_async_new_(struct event_base *base, 203*663afb9bSAndroid Build Coastguard Worker evutil_socket_t fd, int options); 204*663afb9bSAndroid Build Coastguard Worker 205*663afb9bSAndroid Build Coastguard Worker /* FIXME document. */ 206*663afb9bSAndroid Build Coastguard Worker void bufferevent_async_set_connected_(struct bufferevent *bev); 207*663afb9bSAndroid Build Coastguard Worker int bufferevent_async_can_connect_(struct bufferevent *bev); 208*663afb9bSAndroid Build Coastguard Worker int bufferevent_async_connect_(struct bufferevent *bev, evutil_socket_t fd, 209*663afb9bSAndroid Build Coastguard Worker const struct sockaddr *sa, int socklen); 210*663afb9bSAndroid Build Coastguard Worker 211*663afb9bSAndroid Build Coastguard Worker #ifdef __cplusplus 212*663afb9bSAndroid Build Coastguard Worker } 213*663afb9bSAndroid Build Coastguard Worker #endif 214*663afb9bSAndroid Build Coastguard Worker 215*663afb9bSAndroid Build Coastguard Worker #endif 216