Go to the documentation of this file.
53 #define EPOLLIN (1U << 0)
54 #define EPOLLPRI (1U << 1)
55 #define EPOLLOUT (1U << 2)
56 #define EPOLLERR (1U << 3)
57 #define EPOLLHUP (1U << 4)
58 #define EPOLLRDNORM (1U << 6)
59 #define EPOLLRDBAND (1U << 7)
60 #define EPOLLWRNORM (1U << 8)
61 #define EPOLLWRBAND (1U << 9)
62 #define EPOLLMSG (1U << 10)
63 #define EPOLLRDHUP (1U << 13)
64 #define EPOLLONESHOT (1U << 31)
66 #define EPOLL_CTL_ADD 1
67 #define EPOLL_CTL_MOD 2
68 #define EPOLL_CTL_DEL 3
114 #define WEPOLL_INTERNAL static
115 #define WEPOLL_INTERNAL_EXTERN static
117 #if defined(__clang__)
118 #pragma clang diagnostic push
119 #pragma clang diagnostic ignored "-Wnonportable-system-include-path"
120 #pragma clang diagnostic ignored "-Wreserved-id-macro"
121 #elif defined(_MSC_VER)
122 #pragma warning(push, 1)
125 #undef WIN32_LEAN_AND_MEAN
126 #define WIN32_LEAN_AND_MEAN
129 #define _WIN32_WINNT 0x0600
131 #include <winsock2.h>
132 #include <ws2tcpip.h>
135 #if defined(__clang__)
136 #pragma clang diagnostic pop
137 #elif defined(_MSC_VER)
147 #define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
150 #ifndef STATUS_SUCCESS
151 #define STATUS_SUCCESS ((NTSTATUS) 0x00000000L)
154 #ifndef STATUS_PENDING
155 #define STATUS_PENDING ((NTSTATUS) 0x00000103L)
158 #ifndef STATUS_CANCELLED
159 #define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L)
162 #ifndef STATUS_NOT_FOUND
163 #define STATUS_NOT_FOUND ((NTSTATUS) 0xC0000225L)
181 #define RTL_CONSTANT_STRING(s) \
182 { sizeof(s) - sizeof((s)[0]), sizeof(s), s }
193 #define RTL_CONSTANT_OBJECT_ATTRIBUTES(ObjectName, Attributes) \
194 { sizeof(OBJECT_ATTRIBUTES), NULL, ObjectName, Attributes, NULL, NULL }
197 #define FILE_OPEN 0x00000001UL
200 #define KEYEDEVENT_WAIT 0x00000001UL
201 #define KEYEDEVENT_WAKE 0x00000002UL
202 #define KEYEDEVENT_ALL_ACCESS \
203 (STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE)
205 #define NT_NTDLL_IMPORT_LIST(X) \
209 (HANDLE FileHandle, \
210 PIO_STATUS_BLOCK IoRequestToCancel, \
211 PIO_STATUS_BLOCK IoStatusBlock)) \
216 (PHANDLE FileHandle, \
217 ACCESS_MASK DesiredAccess, \
218 POBJECT_ATTRIBUTES ObjectAttributes, \
219 PIO_STATUS_BLOCK IoStatusBlock, \
220 PLARGE_INTEGER AllocationSize, \
221 ULONG FileAttributes, \
223 ULONG CreateDisposition, \
224 ULONG CreateOptions, \
230 NtCreateKeyedEvent, \
231 (PHANDLE KeyedEventHandle, \
232 ACCESS_MASK DesiredAccess, \
233 POBJECT_ATTRIBUTES ObjectAttributes, \
238 NtDeviceIoControlFile, \
239 (HANDLE FileHandle, \
241 PIO_APC_ROUTINE ApcRoutine, \
243 PIO_STATUS_BLOCK IoStatusBlock, \
244 ULONG IoControlCode, \
246 ULONG InputBufferLength, \
247 PVOID OutputBuffer, \
248 ULONG OutputBufferLength)) \
252 NtReleaseKeyedEvent, \
253 (HANDLE KeyedEventHandle, \
256 PLARGE_INTEGER Timeout)) \
260 NtWaitForKeyedEvent, \
261 (HANDLE KeyedEventHandle, \
264 PLARGE_INTEGER Timeout)) \
266 X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status))
268 #define X(return_type, attributes, name, parameters) \
269 WEPOLL_INTERNAL_EXTERN return_type(attributes* name) parameters;
273 #define AFD_POLL_RECEIVE 0x0001
274 #define AFD_POLL_RECEIVE_EXPEDITED 0x0002
275 #define AFD_POLL_SEND 0x0004
276 #define AFD_POLL_DISCONNECT 0x0008
277 #define AFD_POLL_ABORT 0x0010
278 #define AFD_POLL_LOCAL_CLOSE 0x0020
279 #define AFD_POLL_ACCEPT 0x0080
280 #define AFD_POLL_CONNECT_FAIL 0x0100
296 HANDLE* afd_device_handle_out);
304 #define return_map_error(value) \
306 err_map_win_error(); \
310 #define return_set_error(value, error) \
312 err_set_win_error(error); \
320 #define IOCTL_AFD_POLL 0x00012024
329 HANDLE* afd_device_handle_out) {
337 status = NtCreateFile(&afd_device_handle,
343 FILE_SHARE_READ | FILE_SHARE_WRITE,
351 if (CreateIoCompletionPort(afd_device_handle, iocp_handle, 0, 0) ==
NULL)
354 if (!SetFileCompletionNotificationModes(afd_device_handle,
355 FILE_SKIP_SET_EVENT_ON_HANDLE))
358 *afd_device_handle_out = afd_device_handle;
362 CloseHandle(afd_device_handle);
372 assert(io_status_block !=
NULL);
375 status = NtDeviceIoControlFile(afd_device_handle,
405 NtCancelIoFileEx(afd_device_handle, io_status_block, &cancel_iosb);
685 #define ERR__ERRNO_MAPPINGS(X) \
686 X(ERROR_ACCESS_DENIED, EACCES) \
687 X(ERROR_ALREADY_EXISTS, EEXIST) \
688 X(ERROR_BAD_COMMAND, EACCES) \
689 X(ERROR_BAD_EXE_FORMAT, ENOEXEC) \
690 X(ERROR_BAD_LENGTH, EACCES) \
691 X(ERROR_BAD_NETPATH, ENOENT) \
692 X(ERROR_BAD_NET_NAME, ENOENT) \
693 X(ERROR_BAD_NET_RESP, ENETDOWN) \
694 X(ERROR_BAD_PATHNAME, ENOENT) \
695 X(ERROR_BROKEN_PIPE, EPIPE) \
696 X(ERROR_CANNOT_MAKE, EACCES) \
697 X(ERROR_COMMITMENT_LIMIT, ENOMEM) \
698 X(ERROR_CONNECTION_ABORTED, ECONNABORTED) \
699 X(ERROR_CONNECTION_ACTIVE, EISCONN) \
700 X(ERROR_CONNECTION_REFUSED, ECONNREFUSED) \
701 X(ERROR_CRC, EACCES) \
702 X(ERROR_DIR_NOT_EMPTY, ENOTEMPTY) \
703 X(ERROR_DISK_FULL, ENOSPC) \
704 X(ERROR_DUP_NAME, EADDRINUSE) \
705 X(ERROR_FILENAME_EXCED_RANGE, ENOENT) \
706 X(ERROR_FILE_NOT_FOUND, ENOENT) \
707 X(ERROR_GEN_FAILURE, EACCES) \
708 X(ERROR_GRACEFUL_DISCONNECT, EPIPE) \
709 X(ERROR_HOST_DOWN, EHOSTUNREACH) \
710 X(ERROR_HOST_UNREACHABLE, EHOSTUNREACH) \
711 X(ERROR_INSUFFICIENT_BUFFER, EFAULT) \
712 X(ERROR_INVALID_ADDRESS, EADDRNOTAVAIL) \
713 X(ERROR_INVALID_FUNCTION, EINVAL) \
714 X(ERROR_INVALID_HANDLE, EBADF) \
715 X(ERROR_INVALID_NETNAME, EADDRNOTAVAIL) \
716 X(ERROR_INVALID_PARAMETER, EINVAL) \
717 X(ERROR_INVALID_USER_BUFFER, EMSGSIZE) \
718 X(ERROR_IO_PENDING, EINPROGRESS) \
719 X(ERROR_LOCK_VIOLATION, EACCES) \
720 X(ERROR_MORE_DATA, EMSGSIZE) \
721 X(ERROR_NETNAME_DELETED, ECONNABORTED) \
722 X(ERROR_NETWORK_ACCESS_DENIED, EACCES) \
723 X(ERROR_NETWORK_BUSY, ENETDOWN) \
724 X(ERROR_NETWORK_UNREACHABLE, ENETUNREACH) \
725 X(ERROR_NOACCESS, EFAULT) \
726 X(ERROR_NONPAGED_SYSTEM_RESOURCES, ENOMEM) \
727 X(ERROR_NOT_ENOUGH_MEMORY, ENOMEM) \
728 X(ERROR_NOT_ENOUGH_QUOTA, ENOMEM) \
729 X(ERROR_NOT_FOUND, ENOENT) \
730 X(ERROR_NOT_LOCKED, EACCES) \
731 X(ERROR_NOT_READY, EACCES) \
732 X(ERROR_NOT_SAME_DEVICE, EXDEV) \
733 X(ERROR_NOT_SUPPORTED, ENOTSUP) \
734 X(ERROR_NO_MORE_FILES, ENOENT) \
735 X(ERROR_NO_SYSTEM_RESOURCES, ENOMEM) \
736 X(ERROR_OPERATION_ABORTED, EINTR) \
737 X(ERROR_OUT_OF_PAPER, EACCES) \
738 X(ERROR_PAGED_SYSTEM_RESOURCES, ENOMEM) \
739 X(ERROR_PAGEFILE_QUOTA, ENOMEM) \
740 X(ERROR_PATH_NOT_FOUND, ENOENT) \
741 X(ERROR_PIPE_NOT_CONNECTED, EPIPE) \
742 X(ERROR_PORT_UNREACHABLE, ECONNRESET) \
743 X(ERROR_PROTOCOL_UNREACHABLE, ENETUNREACH) \
744 X(ERROR_REM_NOT_LIST, ECONNREFUSED) \
745 X(ERROR_REQUEST_ABORTED, EINTR) \
746 X(ERROR_REQ_NOT_ACCEP, EWOULDBLOCK) \
747 X(ERROR_SECTOR_NOT_FOUND, EACCES) \
748 X(ERROR_SEM_TIMEOUT, ETIMEDOUT) \
749 X(ERROR_SHARING_VIOLATION, EACCES) \
750 X(ERROR_TOO_MANY_NAMES, ENOMEM) \
751 X(ERROR_TOO_MANY_OPEN_FILES, EMFILE) \
752 X(ERROR_UNEXP_NET_ERR, ECONNABORTED) \
753 X(ERROR_WAIT_NO_CHILDREN, ECHILD) \
754 X(ERROR_WORKING_SET_QUOTA, ENOMEM) \
755 X(ERROR_WRITE_PROTECT, EACCES) \
756 X(ERROR_WRONG_DISK, EACCES) \
757 X(WSAEACCES, EACCES) \
758 X(WSAEADDRINUSE, EADDRINUSE) \
759 X(WSAEADDRNOTAVAIL, EADDRNOTAVAIL) \
760 X(WSAEAFNOSUPPORT, EAFNOSUPPORT) \
761 X(WSAECONNABORTED, ECONNABORTED) \
762 X(WSAECONNREFUSED, ECONNREFUSED) \
763 X(WSAECONNRESET, ECONNRESET) \
764 X(WSAEDISCON, EPIPE) \
765 X(WSAEFAULT, EFAULT) \
766 X(WSAEHOSTDOWN, EHOSTUNREACH) \
767 X(WSAEHOSTUNREACH, EHOSTUNREACH) \
768 X(WSAEINPROGRESS, EBUSY) \
770 X(WSAEINVAL, EINVAL) \
771 X(WSAEISCONN, EISCONN) \
772 X(WSAEMSGSIZE, EMSGSIZE) \
773 X(WSAENETDOWN, ENETDOWN) \
774 X(WSAENETRESET, EHOSTUNREACH) \
775 X(WSAENETUNREACH, ENETUNREACH) \
776 X(WSAENOBUFS, ENOMEM) \
777 X(WSAENOTCONN, ENOTCONN) \
778 X(WSAENOTSOCK, ENOTSOCK) \
779 X(WSAEOPNOTSUPP, EOPNOTSUPP) \
780 X(WSAEPROCLIM, ENOMEM) \
781 X(WSAESHUTDOWN, EPIPE) \
782 X(WSAETIMEDOUT, ETIMEDOUT) \
783 X(WSAEWOULDBLOCK, EWOULDBLOCK) \
784 X(WSANOTINITIALISED, ENETDOWN) \
785 X(WSASYSNOTREADY, ENETDOWN) \
786 X(WSAVERNOTSUPPORTED, ENOSYS)
790 #define X(error_sym, errno_sym) \
813 if (handle == INVALID_HANDLE_VALUE)
816 if (!GetHandleInformation(handle, &
flags))
824 #define array_count(a) (sizeof(a) / (sizeof((a)[0])))
826 #define container_of(ptr, type, member) \
827 ((type*) ((uintptr_t) (ptr) - offsetof(type, member)))
829 #define unused_var(v) ((void) (v))
832 #if defined(_MSC_VER) && _MSC_VER < 1900
833 #define inline __inline
882 #define X(return_type, attributes, name, parameters) \
883 WEPOLL_INTERNAL return_type(attributes* name) parameters = NULL;
891 ntdll = GetModuleHandleW(L
"ntdll.dll");
895 #define X(return_type, attributes, name, parameters) \
896 fn_ptr = GetProcAddress(ntdll, #name); \
897 if (fn_ptr == NULL) \
899 name = (return_type(attributes*) parameters)(nt__fn_ptr_cast_t) fn_ptr;
946 #define POLL_GROUP__MAX_GROUP_SIZE 32
1051 #define PORT__MAX_ON_STACK_COMPLETIONS 256
1073 assert(port !=
NULL);
1079 CreateIoCompletionPort(INVALID_HANDLE_VALUE,
NULL, 0, 0);
1080 if (iocp_handle ==
NULL)
1095 if (iocp_handle ==
NULL)
1108 *iocp_handle_out = iocp_handle;
1121 if (!CloseHandle(iocp_handle))
1193 OVERLAPPED_ENTRY* iocp_events,
1194 DWORD iocp_event_count) {
1195 int epoll_event_count = 0;
1198 for (
i = 0;
i < iocp_event_count;
i++) {
1201 struct epoll_event* ev = &epoll_events[epoll_event_count];
1206 return epoll_event_count;
1211 OVERLAPPED_ENTRY* iocp_events,
1214 DWORD completion_count;
1238 port_state, epoll_events, iocp_events, completion_count);
1246 OVERLAPPED_ENTRY* iocp_events;
1257 if ((
size_t) maxevents <=
array_count(stack_iocp_events)) {
1258 iocp_events = stack_iocp_events;
1259 }
else if ((iocp_events =
1260 malloc((
size_t) maxevents *
sizeof *iocp_events)) ==
NULL) {
1261 iocp_events = stack_iocp_events;
1268 due = GetTickCount64() + (uint64_t)
timeout;
1269 gqcs_timeout = (DWORD)
timeout;
1273 gqcs_timeout = INFINITE;
1285 if (result < 0 || result > 0)
1292 now = GetTickCount64();
1296 SetLastError(WAIT_TIMEOUT);
1301 gqcs_timeout = (DWORD)(due - now);
1308 if (iocp_events != stack_iocp_events)
1313 else if (GetLastError() == WAIT_TIMEOUT)
1517 return node->
prev != node;
1520 #define REFLOCK__REF ((long) 0x00000001UL)
1521 #define REFLOCK__REF_MASK ((long) 0x0fffffffUL)
1522 #define REFLOCK__DESTROY ((long) 0x10000000UL)
1523 #define REFLOCK__DESTROY_MASK ((long) 0xf0000000UL)
1524 #define REFLOCK__POISON ((long) 0x300dead0UL)
1529 NTSTATUS status = NtCreateKeyedEvent(
1587 #define SOCK__KNOWN_EPOLL_EVENTS \
1588 (EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDNORM | \
1589 EPOLLRDBAND | EPOLLWRNORM | EPOLLWRBAND | EPOLLMSG | EPOLLRDHUP)
1640 if (socket == 0 || socket == INVALID_SOCKET)
1644 if (base_socket == INVALID_SOCKET)
1752 uint32_t epoll_events = 0;
1769 return epoll_events;
1808 switch (GetLastError()) {
1809 case ERROR_IO_PENDING:
1812 case ERROR_INVALID_HANDLE:
1840 uint32_t epoll_events = 0;
1876 if (epoll_events == 0)
1885 ev->
events = epoll_events;
1977 memset(node, 0,
sizeof *node);
1980 #define TREE__ROTATE(cis, trans) \
1981 tree_node_t* p = node; \
1982 tree_node_t* q = node->trans; \
1983 tree_node_t* parent = p->parent; \
1986 if (parent->left == p) \
1989 parent->right = q; \
1994 q->parent = parent; \
1996 p->trans = q->cis; \
1998 p->trans->parent = p; \
2009 #define TREE__INSERT_OR_DESCEND(side) \
2010 if (parent->side) { \
2011 parent = parent->side; \
2013 parent->side = node; \
2017 #define TREE__REBALANCE_AFTER_INSERT(cis, trans) \
2018 tree_node_t* grandparent = parent->parent; \
2019 tree_node_t* uncle = grandparent->trans; \
2021 if (uncle && uncle->red) { \
2022 parent->red = uncle->red = false; \
2023 grandparent->red = true; \
2024 node = grandparent; \
2026 if (node == parent->trans) { \
2027 tree__rotate_##cis(tree, parent); \
2029 parent = node->parent; \
2031 parent->red = false; \
2032 grandparent->red = true; \
2033 tree__rotate_##trans(tree, grandparent); \
2042 if (key < parent->
key) {
2044 }
else if (
key > parent->
key) {
2059 for (; parent && parent->
red; parent = node->
parent) {
2071 #define TREE__REBALANCE_AFTER_REMOVE(cis, trans) \
2072 tree_node_t* sibling = parent->trans; \
2074 if (sibling->red) { \
2075 sibling->red = false; \
2076 parent->red = true; \
2077 tree__rotate_##cis(tree, parent); \
2078 sibling = parent->trans; \
2080 if ((sibling->left && sibling->left->red) || \
2081 (sibling->right && sibling->right->red)) { \
2082 if (!sibling->trans || !sibling->trans->red) { \
2083 sibling->cis->red = false; \
2084 sibling->red = true; \
2085 tree__rotate_##trans(tree, sibling); \
2086 sibling = parent->trans; \
2088 sibling->red = parent->red; \
2089 parent->red = sibling->trans->red = false; \
2090 tree__rotate_##cis(tree, parent); \
2091 node = tree->root; \
2094 sibling->red = true;
2105 }
else if (!right) {
2114 if (parent->
left == node)
2122 if (
left && right) {
2127 if (
next != right) {
2128 parent =
next->parent;
2131 parent->
left = node;
2132 next->right = right;
2135 next->parent = parent;
2148 if (node && node->
red) {
2156 if (node == parent->
left) {
2163 }
while (!node->
red);
2172 if (key < node->
key)
2174 else if (
key > node->
key)
2186 #ifndef SIO_BSP_HANDLE_POLL
2187 #define SIO_BSP_HANDLE_POLL 0x4800001D
2190 #ifndef SIO_BASE_HANDLE
2191 #define SIO_BASE_HANDLE 0x48000022
2198 r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
2209 if (WSAIoctl(socket,
2217 NULL) != SOCKET_ERROR)
2220 return INVALID_SOCKET;
2229 if (base_socket != INVALID_SOCKET)
2232 error = GetLastError();
2233 if (
error == WSAENOTSOCK)
2248 if (base_socket != INVALID_SOCKET && base_socket != socket)
2249 socket = base_socket;
WEPOLL_INTERNAL int port_register_socket(port_state_t *port_state, sock_state_t *sock_state, SOCKET socket)
WEPOLL_INTERNAL int init(void)
struct tree_node tree_node_t
struct _AFD_POLL_INFO * PAFD_POLL_INFO
WEPOLL_INTERNAL queue_t * port_get_poll_group_queue(port_state_t *port_state)
WEPOLL_INTERNAL poll_group_t * poll_group_acquire(port_state_t *port)
WEPOLL_INTERNAL ts_tree_node_t * port_state_to_handle_tree_node(port_state_t *port_state)
WEPOLL_INTERNAL void ts_tree_node_init(ts_tree_node_t *node)
WEPOLL_INTERNAL tree_node_t * tree_find(const tree_t *tree, uintptr_t key)
WEPOLL_INTERNAL void ts_tree_node_unref(ts_tree_node_t *node)
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(ObjectName, Attributes)
#define TREE__REBALANCE_AFTER_REMOVE(cis, trans)
struct _OBJECT_ATTRIBUTES OBJECT_ATTRIBUTES
#define NT_SUCCESS(status)
static poll_group_t * poll_group__new(port_state_t *port_state)
struct poll_group poll_group_t
WEPOLL_INTERNAL sock_state_t * sock_new(port_state_t *port_state, SOCKET socket)
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
WEPOLL_INTERNAL int sock_set_event(port_state_t *port_state, sock_state_t *sock_state, const struct epoll_event *ev)
#define REFLOCK__DESTROY_MASK
static int port__ctl_mod(port_state_t *port_state, SOCKET sock, struct epoll_event *ev)
#define AFD_POLL_LOCAL_CLOSE
WEPOLL_INTERNAL ts_tree_node_t * ts_tree_find_and_ref(ts_tree_t *ts_tree, uintptr_t key)
#define PORT__MAX_ON_STACK_COMPLETIONS
static SOCKET ws__ioctl_get_bsp_socket(SOCKET socket, DWORD ioctl)
static HANDLE epoll__create(void)
WEPOLL_INTERNAL void queue_init(queue_t *queue)
WEPOLL_INTERNAL SOCKET ws_get_base_socket(SOCKET socket)
WEPOLL_INTERNAL void port_add_deleted_socket(port_state_t *port_state, sock_state_t *sock_state)
WEPOLL_INTERNAL int ts_tree_add(ts_tree_t *ts_tree, ts_tree_node_t *node, uintptr_t key)
struct _AFD_POLL_HANDLE_INFO AFD_POLL_HANDLE_INFO
WEPOLL_INTERNAL bool queue_is_enqueued(const queue_node_t *node)
port_state_t * port_state
WEPOLL_INTERNAL void port_cancel_socket_update(port_state_t *port_state, sock_state_t *sock_state)
static int port__update_events(port_state_t *port_state)
WEPOLL_INTERNAL void reflock_unref(reflock_t *reflock)
#define return_map_error(value)
static void sock__free(sock_state_t *sock_state)
WEPOLL_INTERNAL void reflock_unref_and_destroy(reflock_t *reflock)
WEPOLL_INTERNAL int err_check_handle(HANDLE handle)
queue_t sock_deleted_queue
WEPOLL_INTERNAL poll_group_t * poll_group_from_queue_node(queue_node_t *queue_node)
WEPOLL_INTERNAL sock_state_t * port_find_socket(port_state_t *port_state, SOCKET socket)
static void queue__detach_node(queue_node_t *node)
WEPOLL_EXPORT HANDLE epoll_create1(int flags)
WEPOLL_EXPORT HANDLE epoll_create(int size)
WEPOLL_INTERNAL int sock_update(port_state_t *port_state, sock_state_t *sock_state)
WEPOLL_INTERNAL port_state_t * port_new(HANDLE *iocp_handle_out)
WEPOLL_INTERNAL void port_unregister_socket(port_state_t *port_state, sock_state_t *sock_state)
WEPOLL_INTERNAL void tree_init(tree_t *tree)
WEPOLL_INTERNAL int afd_create_device_handle(HANDLE iocp_handle, HANDLE *afd_device_handle_out)
static BOOL CALLBACK init__once_callback(INIT_ONCE *once, void *parameter, void **context)
static int port__poll(port_state_t *port_state, struct epoll_event *epoll_events, OVERLAPPED_ENTRY *iocp_events, DWORD maxevents, DWORD timeout)
static void reflock__await_event(void *address)
WEPOLL_INTERNAL HANDLE port_get_iocp_handle(port_state_t *port_state)
FARPROC nt__fn_ptr_cast_t
#define POLL_GROUP__MAX_GROUP_SIZE
static DWORD sock__epoll_events_to_afd_events(uint32_t epoll_events)
AFD_POLL_HANDLE_INFO Handles[1]
WEPOLL_INTERNAL int port_ctl(port_state_t *port_state, int op, SOCKET sock, struct epoll_event *ev)
static uint32_t sock__afd_events_to_epoll_events(DWORD afd_events)
union epoll_data epoll_data_t
#define return_set_error(value, error)
WEPOLL_INTERNAL ts_tree_node_t * ts_tree_del_and_ref(ts_tree_t *ts_tree, uintptr_t key)
WEPOLL_INTERNAL void sock_force_delete(port_state_t *port_state, sock_state_t *sock_state)
struct _UNICODE_STRING * PUNICODE_STRING
#define AFD_POLL_DISCONNECT
static HANDLE port__create_iocp(void)
static INIT_ONCE init__once
WEPOLL_INTERNAL int tree_add(tree_t *tree, tree_node_t *node, uintptr_t key)
WEPOLL_INTERNAL void queue_move_to_end(queue_t *queue, queue_node_t *node)
WEPOLL_INTERNAL void sock_delete(port_state_t *port_state, sock_state_t *sock_state)
#define TREE__REBALANCE_AFTER_INSERT(cis, trans)
ts_tree_node_t handle_tree_node
WEPOLL_EXPORT int epoll_ctl(HANDLE ephnd, int op, SOCKET sock, struct epoll_event *event)
static void tree__rotate_right(tree_t *tree, tree_node_t *node)
WEPOLL_INTERNAL queue_node_t * sock_state_to_queue_node(sock_state_t *sock_state)
struct sock_state sock_state_t
struct _UNICODE_STRING UNICODE_STRING
WEPOLL_INTERNAL void ts_tree_node_unref_and_destroy(ts_tree_node_t *node)
WEPOLL_INTERNAL void queue_append(queue_t *queue, queue_node_t *node)
WEPOLL_INTERNAL void tree_del(tree_t *tree, tree_node_t *node)
#define container_of(ptr, type, member)
WEPOLL_INTERNAL tree_node_t * sock_state_to_tree_node(sock_state_t *sock_state)
static HANDLE reflock__keyed_event
WEPOLL_INTERNAL void err_set_win_error(DWORD error)
#define TREE__ROTATE(cis, trans)
WEPOLL_INTERNAL void ts_tree_init(ts_tree_t *rtl)
static UPB_NORETURN void err(tarjan *t)
GLbitfield GLuint64 timeout
static int sock__cancel_poll(sock_state_t *sock_state)
poll_group_t * poll_group
WEPOLL_INTERNAL void poll_group_release(poll_group_t *poll_group)
WEPOLL_INTERNAL bool queue_is_empty(const queue_t *queue)
WEPOLL_INTERNAL int port_wait(port_state_t *port_state, struct epoll_event *events, int maxevents, int timeout)
WEPOLL_INTERNAL int sock_feed_event(port_state_t *port_state, IO_STATUS_BLOCK *io_status_block, struct epoll_event *ev)
static port_state_t * port__alloc(void)
#define SOCK__KNOWN_EPOLL_EVENTS
const SETUP_TEARDOWN_TESTCONTEXT char * key
struct queue_node queue_node_t
static errno_t err__map_win_error_to_errno(DWORD error)
VOID(NTAPI * PIO_APC_ROUTINE)(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
WEPOLL_INTERNAL void tree_node_init(tree_node_t *node)
struct _AFD_POLL_HANDLE_INFO * PAFD_POLL_HANDLE_INFO
struct _OBJECT_ATTRIBUTES * POBJECT_ATTRIBUTES
static int port__ctl_del(port_state_t *port_state, SOCKET sock)
static int port__feed_events(port_state_t *port_state, struct epoll_event *epoll_events, OVERLAPPED_ENTRY *iocp_events, DWORD iocp_event_count)
struct port_state port_state_t
static int port__ctl_op(port_state_t *port_state, int op, SOCKET sock, struct epoll_event *ev)
WEPOLL_INTERNAL sock_state_t * sock_state_from_tree_node(tree_node_t *tree_node)
#define X(return_type, attributes, name, parameters)
WEPOLL_INTERNAL void queue_prepend(queue_t *queue, queue_node_t *node)
static int port__close_iocp(port_state_t *port_state)
struct ts_tree_node ts_tree_node_t
WEPOLL_INTERNAL void poll_group_delete(poll_group_t *poll_group)
#define SIO_BSP_HANDLE_POLL
WEPOLL_INTERNAL sock_state_t * sock_state_from_queue_node(queue_node_t *queue_node)
#define KEYEDEVENT_ALL_ACCESS
sock__poll_status_t poll_status
#define REFLOCK__REF_MASK
queue_t sock_update_queue
WEPOLL_INTERNAL int epoll_global_init(void)
WEPOLL_INTERNAL void err_map_win_error(void)
static UNICODE_STRING afd__device_name
WEPOLL_INTERNAL queue_node_t * queue_last(const queue_t *queue)
WEPOLL_INTERNAL void queue_move_to_start(queue_t *queue, queue_node_t *node)
static void reflock__signal_event(void *address)
static void port__free(port_state_t *port)
WEPOLL_INTERNAL int afd_cancel_poll(HANDLE afd_device_handle, IO_STATUS_BLOCK *io_status_block)
WEPOLL_EXPORT int epoll_wait(HANDLE ephnd, struct epoll_event *events, int maxevents, int timeout)
WEPOLL_INTERNAL void queue_node_init(queue_node_t *node)
PUNICODE_STRING ObjectName
WEPOLL_INTERNAL port_state_t * port_state_from_handle_tree_node(ts_tree_node_t *tree_node)
static ts_tree_t epoll__handle_tree
WEPOLL_INTERNAL int port_delete(port_state_t *port_state)
static ts_tree_node_t * ts_tree__find_node(ts_tree_t *ts_tree, uintptr_t key)
#define AFD_POLL_RECEIVE_EXPEDITED
WEPOLL_INTERNAL int port_close(port_state_t *port_state)
struct _AFD_POLL_INFO AFD_POLL_INFO
WEPOLL_INTERNAL int nt_global_init(void)
enum sock__poll_status sock__poll_status_t
struct _IO_STATUS_BLOCK IO_STATUS_BLOCK
#define ERR__ERRNO_MAPPINGS(X)
#define AFD_POLL_CONNECT_FAIL
WEPOLL_INTERNAL queue_node_t * queue_first(const queue_t *queue)
WEPOLL_INTERNAL void port_remove_deleted_socket(port_state_t *port_state, sock_state_t *sock_state)
#define RTL_CONSTANT_STRING(s)
WEPOLL_INTERNAL void reflock_ref(reflock_t *reflock)
static OBJECT_ATTRIBUTES afd__device_attributes
WEPOLL_EXPORT int epoll_close(HANDLE ephnd)
IO_STATUS_BLOCK io_status_block
static void tree__rotate_left(tree_t *tree, tree_node_t *node)
WEPOLL_INTERNAL void reflock_init(reflock_t *reflock)
static size_t next(const upb_table *t, size_t i)
#define NT_NTDLL_IMPORT_LIST(X)
WEPOLL_INTERNAL HANDLE poll_group_get_afd_device_handle(poll_group_t *poll_group)
WEPOLL_INTERNAL int afd_poll(HANDLE afd_device_handle, AFD_POLL_INFO *poll_info, IO_STATUS_BLOCK *io_status_block)
WEPOLL_INTERNAL void port_request_socket_update(port_state_t *port_state, sock_state_t *sock_state)
WEPOLL_INTERNAL void queue_remove(queue_node_t *node)
static void port__update_events_if_polling(port_state_t *port_state)
WEPOLL_INTERNAL tree_node_t * tree_root(const tree_t *tree)
WEPOLL_INTERNAL int ws_global_init(void)
WEPOLL_INTERNAL int reflock_global_init(void)
static int sock__delete(port_state_t *port_state, sock_state_t *sock_state, bool force)
#define TREE__INSERT_OR_DESCEND(side)
static int port__ctl_add(port_state_t *port_state, SOCKET sock, struct epoll_event *ev)
static sock_state_t * sock__alloc(void)
PVOID SecurityQualityOfService
libaditof
Author(s):
autogenerated on Wed May 21 2025 02:07:01