1ca737ff3SNick Mathewson /* 2e49e2891SNick Mathewson * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson 3ca737ff3SNick Mathewson * 4ca737ff3SNick Mathewson * Redistribution and use in source and binary forms, with or without 5ca737ff3SNick Mathewson * modification, are permitted provided that the following conditions 6ca737ff3SNick Mathewson * are met: 7ca737ff3SNick Mathewson * 1. Redistributions of source code must retain the above copyright 8ca737ff3SNick Mathewson * notice, this list of conditions and the following disclaimer. 9ca737ff3SNick Mathewson * 2. Redistributions in binary form must reproduce the above copyright 10ca737ff3SNick Mathewson * notice, this list of conditions and the following disclaimer in the 11ca737ff3SNick Mathewson * documentation and/or other materials provided with the distribution. 12ca737ff3SNick Mathewson * 3. The name of the author may not be used to endorse or promote products 13ca737ff3SNick Mathewson * derived from this software without specific prior written permission. 14ca737ff3SNick Mathewson * 15ca737ff3SNick Mathewson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16ca737ff3SNick Mathewson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17ca737ff3SNick Mathewson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18ca737ff3SNick Mathewson * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19ca737ff3SNick Mathewson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20ca737ff3SNick Mathewson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21ca737ff3SNick Mathewson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22ca737ff3SNick Mathewson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23ca737ff3SNick Mathewson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24ca737ff3SNick Mathewson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25ca737ff3SNick Mathewson */ 26ca737ff3SNick Mathewson 273f8c7cd0SNick Mathewson #ifndef IOCP_INTERNAL_H_INCLUDED_ 283f8c7cd0SNick Mathewson #define IOCP_INTERNAL_H_INCLUDED_ 29ca737ff3SNick Mathewson 30ca737ff3SNick Mathewson #ifdef __cplusplus 31ca737ff3SNick Mathewson extern "C" { 32ca737ff3SNick Mathewson #endif 33ca737ff3SNick Mathewson 3493d4f884SNick Mathewson struct event_overlapped; 35838d0a81SNick Mathewson struct event_iocp_port; 36838d0a81SNick Mathewson struct evbuffer; 37cef61a2fSNick Mathewson typedef void (*iocp_callback)(struct event_overlapped *, ev_uintptr_t, ev_ssize_t, int success); 38ca737ff3SNick Mathewson 39838d0a81SNick Mathewson /* This whole file is actually win32 only. We wrap the structures in a win32 40838d0a81SNick Mathewson * ifdef so that we can test-compile code that uses these interfaces on 41838d0a81SNick Mathewson * non-win32 platforms. */ 429f560bfaSNick Mathewson #ifdef _WIN32 43838d0a81SNick Mathewson 44838d0a81SNick Mathewson /** 45838d0a81SNick Mathewson Internal use only. Wraps an OVERLAPPED that we're using for libevent 46838d0a81SNick Mathewson functionality. Whenever an event_iocp_port gets an event for a given 47838d0a81SNick Mathewson OVERLAPPED*, it upcasts the pointer to an event_overlapped, and calls the 48838d0a81SNick Mathewson iocp_callback function with the event_overlapped, the iocp key, and the 49838d0a81SNick Mathewson number of bytes transferred as arguments. 50838d0a81SNick Mathewson */ 51ca737ff3SNick Mathewson struct event_overlapped { 52ca737ff3SNick Mathewson OVERLAPPED overlapped; 53ca737ff3SNick Mathewson iocp_callback cb; 54ca737ff3SNick Mathewson }; 55ca737ff3SNick Mathewson 56fa313f28SNick Mathewson /* Mingw's headers don't define LPFN_ACCEPTEX. */ 57fa313f28SNick Mathewson 58fa313f28SNick Mathewson typedef BOOL (WINAPI *AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED); 59fa313f28SNick Mathewson typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const struct sockaddr *, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED); 60fa313f28SNick Mathewson typedef void (WINAPI *GetAcceptExSockaddrsPtr)(PVOID, DWORD, DWORD, DWORD, LPSOCKADDR *, LPINT, LPSOCKADDR *, LPINT); 61fa313f28SNick Mathewson 62fa313f28SNick Mathewson /** Internal use only. Holds pointers to functions that only some versions of 63fa313f28SNick Mathewson Windows provide. 64fa313f28SNick Mathewson */ 65fa313f28SNick Mathewson struct win32_extension_fns { 66fa313f28SNick Mathewson AcceptExPtr AcceptEx; 67fa313f28SNick Mathewson ConnectExPtr ConnectEx; 68fa313f28SNick Mathewson GetAcceptExSockaddrsPtr GetAcceptExSockaddrs; 69fa313f28SNick Mathewson }; 70fa313f28SNick Mathewson 71838d0a81SNick Mathewson /** 72838d0a81SNick Mathewson Internal use only. Stores a Windows IO Completion port, along with 73838d0a81SNick Mathewson related data. 74838d0a81SNick Mathewson */ 75ca737ff3SNick Mathewson struct event_iocp_port { 76838d0a81SNick Mathewson /** The port itself */ 77ca737ff3SNick Mathewson HANDLE port; 78f1090833SNick Mathewson /* A lock to cover internal structures. */ 79f1090833SNick Mathewson CRITICAL_SECTION lock; 80f1090833SNick Mathewson /** Number of threads ever open on the port. */ 81f1090833SNick Mathewson short n_threads; 82838d0a81SNick Mathewson /** True iff we're shutting down all the threads on this port */ 83f1090833SNick Mathewson short shutdown; 84838d0a81SNick Mathewson /** How often the threads on this port check for shutdown and other 85838d0a81SNick Mathewson * conditions */ 860b987813SNick Mathewson long ms; 87f1090833SNick Mathewson /* The threads that are waiting for events. */ 88f1090833SNick Mathewson HANDLE *threads; 89f1090833SNick Mathewson /** Number of threads currently open on this port. */ 90f1090833SNick Mathewson short n_live_threads; 91fa313f28SNick Mathewson /** A semaphore to signal when we are done shutting down. */ 92f1090833SNick Mathewson HANDLE *shutdownSemaphore; 93f1090833SNick Mathewson }; 94fa313f28SNick Mathewson 95*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 968ac3c4c2SNick Mathewson const struct win32_extension_fns *event_get_win32_extension_fns_(void); 97f1090833SNick Mathewson #else 98f1090833SNick Mathewson /* Dummy definition so we can test-compile more things on unix. */ 99f1090833SNick Mathewson struct event_overlapped { 100f1090833SNick Mathewson iocp_callback cb; 101ca737ff3SNick Mathewson }; 102838d0a81SNick Mathewson #endif 103ca737ff3SNick Mathewson 104838d0a81SNick Mathewson /** Initialize the fields in an event_overlapped. 105838d0a81SNick Mathewson 106838d0a81SNick Mathewson @param overlapped The struct event_overlapped to initialize 107838d0a81SNick Mathewson @param cb The callback that should be invoked once the IO operation has 108838d0a81SNick Mathewson finished. 109838d0a81SNick Mathewson */ 110*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1118ac3c4c2SNick Mathewson void event_overlapped_init_(struct event_overlapped *, iocp_callback cb); 112838d0a81SNick Mathewson 113838d0a81SNick Mathewson /** Allocate and return a new evbuffer that supports overlapped IO on a given 114838d0a81SNick Mathewson socket. The socket must be associated with an IO completion port using 1158ac3c4c2SNick Mathewson event_iocp_port_associate_. 116838d0a81SNick Mathewson */ 117*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1188ac3c4c2SNick Mathewson struct evbuffer *evbuffer_overlapped_new_(evutil_socket_t fd); 119838d0a81SNick Mathewson 12031d89f27SNick Mathewson /** XXXX Document (nickm) */ 121cb9da0bfSNick Mathewson evutil_socket_t evbuffer_overlapped_get_fd_(struct evbuffer *buf); 12231d89f27SNick Mathewson 123cb9da0bfSNick Mathewson void evbuffer_overlapped_set_fd_(struct evbuffer *buf, evutil_socket_t fd); 12486db1c85SNick Mathewson 125838d0a81SNick Mathewson /** Start reading data onto the end of an overlapped evbuffer. 126838d0a81SNick Mathewson 127838d0a81SNick Mathewson An evbuffer can only have one read pending at a time. While the read 128838d0a81SNick Mathewson is in progress, no other data may be added to the end of the buffer. 1298ac3c4c2SNick Mathewson The buffer must be created with event_overlapped_init_(). 1308ac3c4c2SNick Mathewson evbuffer_commit_read_() must be called in the completion callback. 131838d0a81SNick Mathewson 132838d0a81SNick Mathewson @param buf The buffer to read onto 133838d0a81SNick Mathewson @param n The number of bytes to try to read. 134d7d1f1daSNick Mathewson @param ol Overlapped object with associated completion callback. 135838d0a81SNick Mathewson @return 0 on success, -1 on error. 136838d0a81SNick Mathewson */ 137*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1388ac3c4c2SNick Mathewson int evbuffer_launch_read_(struct evbuffer *buf, size_t n, struct event_overlapped *ol); 139838d0a81SNick Mathewson 140838d0a81SNick Mathewson /** Start writing data from the start of an evbuffer. 141838d0a81SNick Mathewson 142838d0a81SNick Mathewson An evbuffer can only have one write pending at a time. While the write is 143838d0a81SNick Mathewson in progress, no other data may be removed from the front of the buffer. 1448ac3c4c2SNick Mathewson The buffer must be created with event_overlapped_init_(). 1458ac3c4c2SNick Mathewson evbuffer_commit_write_() must be called in the completion callback. 146838d0a81SNick Mathewson 147838d0a81SNick Mathewson @param buf The buffer to read onto 148838d0a81SNick Mathewson @param n The number of bytes to try to read. 149d7d1f1daSNick Mathewson @param ol Overlapped object with associated completion callback. 150838d0a81SNick Mathewson @return 0 on success, -1 on error. 151838d0a81SNick Mathewson */ 152*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1538ac3c4c2SNick Mathewson int evbuffer_launch_write_(struct evbuffer *buf, ev_ssize_t n, struct event_overlapped *ol); 154d7d1f1daSNick Mathewson 155d7d1f1daSNick Mathewson /** XXX document */ 156*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1578ac3c4c2SNick Mathewson void evbuffer_commit_read_(struct evbuffer *, ev_ssize_t); 158*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1598ac3c4c2SNick Mathewson void evbuffer_commit_write_(struct evbuffer *, ev_ssize_t); 1600b987813SNick Mathewson 161838d0a81SNick Mathewson /** Create an IOCP, and launch its worker threads. Internal use only. 162838d0a81SNick Mathewson 163838d0a81SNick Mathewson This interface is unstable, and will change. 164838d0a81SNick Mathewson */ 165*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1668ac3c4c2SNick Mathewson struct event_iocp_port *event_iocp_port_launch_(int n_cpus); 167838d0a81SNick Mathewson 168838d0a81SNick Mathewson /** Associate a file descriptor with an iocp, such that overlapped IO on the 169838d0a81SNick Mathewson fd will happen on one of the iocp's worker threads. 170838d0a81SNick Mathewson */ 171*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1728ac3c4c2SNick Mathewson int event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd, 173cef61a2fSNick Mathewson ev_uintptr_t key); 174838d0a81SNick Mathewson 175f1090833SNick Mathewson /** Tell all threads serving an iocp to stop. Wait for up to waitMsec for all 176d844242fSChristopher Davis the threads to finish whatever they're doing. If waitMsec is -1, wait 177d844242fSChristopher Davis as long as required. If all the threads are done, free the port and return 178d844242fSChristopher Davis 0. Otherwise, return -1. If you get a -1 return value, it is safe to call 179d844242fSChristopher Davis this function again. 180f1090833SNick Mathewson */ 181*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1828ac3c4c2SNick Mathewson int event_iocp_shutdown_(struct event_iocp_port *port, long waitMsec); 183f1090833SNick Mathewson 184f1090833SNick Mathewson /* FIXME document. */ 185*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1868ac3c4c2SNick Mathewson int event_iocp_activate_overlapped_(struct event_iocp_port *port, 187f1090833SNick Mathewson struct event_overlapped *o, 188cef61a2fSNick Mathewson ev_uintptr_t key, ev_uint32_t n_bytes); 189f1090833SNick Mathewson 190fe47003dSNick Mathewson struct event_base; 191879420a7SNick Mathewson /* FIXME document. */ 192*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 1938ac3c4c2SNick Mathewson struct event_iocp_port *event_base_get_iocp_(struct event_base *base); 19493d4f884SNick Mathewson 195879420a7SNick Mathewson /* FIXME document. */ 1969806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 1978ac3c4c2SNick Mathewson int event_base_start_iocp_(struct event_base *base, int n_cpus); 1988ac3c4c2SNick Mathewson void event_base_stop_iocp_(struct event_base *base); 199879420a7SNick Mathewson 200879420a7SNick Mathewson /* FIXME document. */ 201*ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 2028ac3c4c2SNick Mathewson struct bufferevent *bufferevent_async_new_(struct event_base *base, 203879420a7SNick Mathewson evutil_socket_t fd, int options); 204879420a7SNick Mathewson 20586db1c85SNick Mathewson /* FIXME document. */ 2068ac3c4c2SNick Mathewson void bufferevent_async_set_connected_(struct bufferevent *bev); 2078ac3c4c2SNick Mathewson int bufferevent_async_can_connect_(struct bufferevent *bev); 2088ac3c4c2SNick Mathewson int bufferevent_async_connect_(struct bufferevent *bev, evutil_socket_t fd, 20986db1c85SNick Mathewson const struct sockaddr *sa, int socklen); 210879420a7SNick Mathewson 211ca737ff3SNick Mathewson #ifdef __cplusplus 212ca737ff3SNick Mathewson } 213ca737ff3SNick Mathewson #endif 214ca737ff3SNick Mathewson 215ca737ff3SNick Mathewson #endif 216