xref: /netbsd-src/external/bsd/ntp/dist/sntp/libevent/iocp-internal.h (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: iocp-internal.h,v 1.6 2024/08/18 20:47:21 christos Exp $	*/
28585484eSchristos 
38585484eSchristos /*
48585484eSchristos  * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
58585484eSchristos  *
68585484eSchristos  * Redistribution and use in source and binary forms, with or without
78585484eSchristos  * modification, are permitted provided that the following conditions
88585484eSchristos  * are met:
98585484eSchristos  * 1. Redistributions of source code must retain the above copyright
108585484eSchristos  *    notice, this list of conditions and the following disclaimer.
118585484eSchristos  * 2. Redistributions in binary form must reproduce the above copyright
128585484eSchristos  *    notice, this list of conditions and the following disclaimer in the
138585484eSchristos  *    documentation and/or other materials provided with the distribution.
148585484eSchristos  * 3. The name of the author may not be used to endorse or promote products
158585484eSchristos  *    derived from this software without specific prior written permission.
168585484eSchristos  *
178585484eSchristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
188585484eSchristos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
198585484eSchristos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
208585484eSchristos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
218585484eSchristos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
228585484eSchristos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238585484eSchristos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248585484eSchristos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258585484eSchristos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
268585484eSchristos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278585484eSchristos  */
288585484eSchristos 
298585484eSchristos #ifndef IOCP_INTERNAL_H_INCLUDED_
308585484eSchristos #define IOCP_INTERNAL_H_INCLUDED_
318585484eSchristos 
328585484eSchristos #ifdef __cplusplus
338585484eSchristos extern "C" {
348585484eSchristos #endif
358585484eSchristos 
368585484eSchristos struct event_overlapped;
378585484eSchristos struct event_iocp_port;
388585484eSchristos struct evbuffer;
398585484eSchristos typedef void (*iocp_callback)(struct event_overlapped *, ev_uintptr_t, ev_ssize_t, int success);
408585484eSchristos 
418585484eSchristos /* This whole file is actually win32 only. We wrap the structures in a win32
428585484eSchristos  * ifdef so that we can test-compile code that uses these interfaces on
438585484eSchristos  * non-win32 platforms. */
448585484eSchristos #ifdef _WIN32
458585484eSchristos 
468585484eSchristos /**
478585484eSchristos    Internal use only.  Wraps an OVERLAPPED that we're using for libevent
488585484eSchristos    functionality.  Whenever an event_iocp_port gets an event for a given
498585484eSchristos    OVERLAPPED*, it upcasts the pointer to an event_overlapped, and calls the
508585484eSchristos    iocp_callback function with the event_overlapped, the iocp key, and the
518585484eSchristos    number of bytes transferred as arguments.
528585484eSchristos  */
538585484eSchristos struct event_overlapped {
548585484eSchristos 	OVERLAPPED overlapped;
558585484eSchristos 	iocp_callback cb;
568585484eSchristos };
578585484eSchristos 
588585484eSchristos /* Mingw's headers don't define LPFN_ACCEPTEX. */
598585484eSchristos 
608585484eSchristos typedef BOOL (WINAPI *AcceptExPtr)(SOCKET, SOCKET, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED);
618585484eSchristos typedef BOOL (WINAPI *ConnectExPtr)(SOCKET, const struct sockaddr *, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED);
628585484eSchristos typedef void (WINAPI *GetAcceptExSockaddrsPtr)(PVOID, DWORD, DWORD, DWORD, LPSOCKADDR *, LPINT, LPSOCKADDR *, LPINT);
638585484eSchristos 
648585484eSchristos /** Internal use only. Holds pointers to functions that only some versions of
658585484eSchristos     Windows provide.
668585484eSchristos  */
678585484eSchristos struct win32_extension_fns {
688585484eSchristos 	AcceptExPtr AcceptEx;
698585484eSchristos 	ConnectExPtr ConnectEx;
708585484eSchristos 	GetAcceptExSockaddrsPtr GetAcceptExSockaddrs;
718585484eSchristos };
728585484eSchristos 
738585484eSchristos /**
748585484eSchristos     Internal use only. Stores a Windows IO Completion port, along with
758585484eSchristos     related data.
768585484eSchristos  */
778585484eSchristos struct event_iocp_port {
788585484eSchristos 	/** The port itself */
798585484eSchristos 	HANDLE port;
808585484eSchristos 	/* A lock to cover internal structures. */
818585484eSchristos 	CRITICAL_SECTION lock;
828585484eSchristos 	/** Number of threads ever open on the port. */
838585484eSchristos 	short n_threads;
848585484eSchristos 	/** True iff we're shutting down all the threads on this port */
858585484eSchristos 	short shutdown;
868585484eSchristos 	/** How often the threads on this port check for shutdown and other
878585484eSchristos 	 * conditions */
888585484eSchristos 	long ms;
898585484eSchristos 	/* The threads that are waiting for events. */
908585484eSchristos 	HANDLE *threads;
918585484eSchristos 	/** Number of threads currently open on this port. */
928585484eSchristos 	short n_live_threads;
938585484eSchristos 	/** A semaphore to signal when we are done shutting down. */
948585484eSchristos 	HANDLE *shutdownSemaphore;
958585484eSchristos };
968585484eSchristos 
97*eabc0478Schristos EVENT2_EXPORT_SYMBOL
988585484eSchristos const struct win32_extension_fns *event_get_win32_extension_fns_(void);
998585484eSchristos #else
1008585484eSchristos /* Dummy definition so we can test-compile more things on unix. */
1018585484eSchristos struct event_overlapped {
1028585484eSchristos 	iocp_callback cb;
1038585484eSchristos };
1048585484eSchristos #endif
1058585484eSchristos 
1068585484eSchristos /** Initialize the fields in an event_overlapped.
1078585484eSchristos 
1088585484eSchristos     @param overlapped The struct event_overlapped to initialize
1098585484eSchristos     @param cb The callback that should be invoked once the IO operation has
1108585484eSchristos 	finished.
1118585484eSchristos  */
112*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1138585484eSchristos void event_overlapped_init_(struct event_overlapped *, iocp_callback cb);
1148585484eSchristos 
1158585484eSchristos /** Allocate and return a new evbuffer that supports overlapped IO on a given
1168585484eSchristos     socket.  The socket must be associated with an IO completion port using
1178585484eSchristos     event_iocp_port_associate_.
1188585484eSchristos */
119*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1208585484eSchristos struct evbuffer *evbuffer_overlapped_new_(evutil_socket_t fd);
1218585484eSchristos 
1228585484eSchristos /** XXXX Document (nickm) */
1238585484eSchristos evutil_socket_t evbuffer_overlapped_get_fd_(struct evbuffer *buf);
1248585484eSchristos 
1258585484eSchristos void evbuffer_overlapped_set_fd_(struct evbuffer *buf, evutil_socket_t fd);
1268585484eSchristos 
1278585484eSchristos /** Start reading data onto the end of an overlapped evbuffer.
1288585484eSchristos 
1298585484eSchristos     An evbuffer can only have one read pending at a time.  While the read
1308585484eSchristos     is in progress, no other data may be added to the end of the buffer.
1318585484eSchristos     The buffer must be created with event_overlapped_init_().
1328585484eSchristos     evbuffer_commit_read_() must be called in the completion callback.
1338585484eSchristos 
1348585484eSchristos     @param buf The buffer to read onto
1358585484eSchristos     @param n The number of bytes to try to read.
1368585484eSchristos     @param ol Overlapped object with associated completion callback.
1378585484eSchristos     @return 0 on success, -1 on error.
1388585484eSchristos  */
139*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1408585484eSchristos int evbuffer_launch_read_(struct evbuffer *buf, size_t n, struct event_overlapped *ol);
1418585484eSchristos 
1428585484eSchristos /** Start writing data from the start of an evbuffer.
1438585484eSchristos 
1448585484eSchristos     An evbuffer can only have one write pending at a time.  While the write is
1458585484eSchristos     in progress, no other data may be removed from the front of the buffer.
1468585484eSchristos     The buffer must be created with event_overlapped_init_().
1478585484eSchristos     evbuffer_commit_write_() must be called in the completion callback.
1488585484eSchristos 
1498585484eSchristos     @param buf The buffer to read onto
1508585484eSchristos     @param n The number of bytes to try to read.
1518585484eSchristos     @param ol Overlapped object with associated completion callback.
1528585484eSchristos     @return 0 on success, -1 on error.
1538585484eSchristos  */
154*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1558585484eSchristos int evbuffer_launch_write_(struct evbuffer *buf, ev_ssize_t n, struct event_overlapped *ol);
1568585484eSchristos 
1578585484eSchristos /** XXX document */
158*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1598585484eSchristos void evbuffer_commit_read_(struct evbuffer *, ev_ssize_t);
160*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1618585484eSchristos void evbuffer_commit_write_(struct evbuffer *, ev_ssize_t);
1628585484eSchristos 
1638585484eSchristos /** Create an IOCP, and launch its worker threads.  Internal use only.
1648585484eSchristos 
1658585484eSchristos     This interface is unstable, and will change.
1668585484eSchristos  */
167*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1688585484eSchristos struct event_iocp_port *event_iocp_port_launch_(int n_cpus);
1698585484eSchristos 
1708585484eSchristos /** Associate a file descriptor with an iocp, such that overlapped IO on the
1718585484eSchristos     fd will happen on one of the iocp's worker threads.
1728585484eSchristos */
173*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1748585484eSchristos int event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd,
1758585484eSchristos     ev_uintptr_t key);
1768585484eSchristos 
1778585484eSchristos /** Tell all threads serving an iocp to stop.  Wait for up to waitMsec for all
1788585484eSchristos     the threads to finish whatever they're doing.  If waitMsec is -1, wait
1798585484eSchristos     as long as required.  If all the threads are done, free the port and return
1808585484eSchristos     0. Otherwise, return -1.  If you get a -1 return value, it is safe to call
1818585484eSchristos     this function again.
1828585484eSchristos */
183*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1848585484eSchristos int event_iocp_shutdown_(struct event_iocp_port *port, long waitMsec);
1858585484eSchristos 
1868585484eSchristos /* FIXME document. */
187*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1888585484eSchristos int event_iocp_activate_overlapped_(struct event_iocp_port *port,
1898585484eSchristos     struct event_overlapped *o,
1908585484eSchristos     ev_uintptr_t key, ev_uint32_t n_bytes);
1918585484eSchristos 
1928585484eSchristos struct event_base;
1938585484eSchristos /* FIXME document. */
194*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1958585484eSchristos struct event_iocp_port *event_base_get_iocp_(struct event_base *base);
1968585484eSchristos 
1978585484eSchristos /* FIXME document. */
198*eabc0478Schristos EVENT2_EXPORT_SYMBOL
1998585484eSchristos int event_base_start_iocp_(struct event_base *base, int n_cpus);
2008585484eSchristos void event_base_stop_iocp_(struct event_base *base);
2018585484eSchristos 
2028585484eSchristos /* FIXME document. */
203*eabc0478Schristos EVENT2_EXPORT_SYMBOL
2048585484eSchristos struct bufferevent *bufferevent_async_new_(struct event_base *base,
2058585484eSchristos     evutil_socket_t fd, int options);
2068585484eSchristos 
2078585484eSchristos /* FIXME document. */
2088585484eSchristos void bufferevent_async_set_connected_(struct bufferevent *bev);
2098585484eSchristos int bufferevent_async_can_connect_(struct bufferevent *bev);
2108585484eSchristos int bufferevent_async_connect_(struct bufferevent *bev, evutil_socket_t fd,
2118585484eSchristos 	const struct sockaddr *sa, int socklen);
2128585484eSchristos 
2138585484eSchristos #ifdef __cplusplus
2148585484eSchristos }
2158585484eSchristos #endif
2168585484eSchristos 
2178585484eSchristos #endif
218