version 1.1.0
This commit is contained in:
commit
c751fb935f
40
README.md
40
README.md
@ -1,18 +1,16 @@
|
|||||||
# wepoll - epoll for windows
|
# wepoll - epoll for windows
|
||||||
|
|
||||||
This library implements the
|
This library implements the [epoll][man epoll] API for Windows
|
||||||
[epoll](http://man7.org/linux/man-pages/man7/epoll.7.html) API for
|
applications. It attempts to be efficient, and to match the Linux API
|
||||||
Windows applications. It attempts to be efficient, and to match the
|
as semantics as closely as possible.
|
||||||
Linux API and as closely as possible.
|
|
||||||
|
|
||||||
## Rationale
|
## Rationale
|
||||||
|
|
||||||
Unlike Linux, OS X, and many other operating systems, Windows doesn't
|
Unlike Linux, OS X, and many other operating systems, Windows doesn't
|
||||||
have a good API for receiving socket state notifications. It only
|
have a good API for receiving socket state notifications. It only
|
||||||
supports the `select` and `WSAPoll` APIs, but they
|
supports the `select` and `WSAPoll` APIs, but they
|
||||||
[don't scale](https://daniel.haxx.se/docs/poll-vs-select.html)
|
[don't scale][select scale] and suffer from
|
||||||
and suffer from
|
[other issues][wsapoll broken].
|
||||||
[other issues](https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/).
|
|
||||||
|
|
||||||
Using I/O completion ports isn't always practical when software is
|
Using I/O completion ports isn't always practical when software is
|
||||||
designed to be cross-platform. Wepoll offers an alternative that is
|
designed to be cross-platform. Wepoll offers an alternative that is
|
||||||
@ -36,9 +34,10 @@ to run on Linux.
|
|||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
The library is distributed as a single source file (wepoll.c) and a
|
The library is [distributed][dist] as a single source file
|
||||||
single header file (wepoll.h). Compile the .c file as part of your
|
([wepoll.c][wepoll.c]) and a single header file ([wepoll.h][wepoll.h]).
|
||||||
project, and include the header wherever needed.
|
Compile the .c file as part of your project, and include the header
|
||||||
|
wherever needed.
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
@ -61,10 +60,10 @@ HANDLE epoll_create1(int flags);
|
|||||||
```
|
```
|
||||||
|
|
||||||
* Create a new epoll instance (port).
|
* Create a new epoll instance (port).
|
||||||
* `size` is ignored but most be nonzero.
|
* `size` is ignored but most be greater than zero.
|
||||||
* `flags` must be zero as there are no supported flags.
|
* `flags` must be zero as there are no supported flags.
|
||||||
* Returns `INVALID_HANDLE_VALUE` on failure.
|
* Returns `INVALID_HANDLE_VALUE` on failure.
|
||||||
* [man page](http://man7.org/linux/man-pages/man2/epoll_create.2.html)
|
* [man page][man epoll_create]
|
||||||
|
|
||||||
### epoll_close
|
### epoll_close
|
||||||
|
|
||||||
@ -94,7 +93,7 @@ int epoll_ctl(HANDLE ephnd,
|
|||||||
wepoll may not be able to detect this until the next call to
|
wepoll may not be able to detect this until the next call to
|
||||||
`epoll_wait()`.
|
`epoll_wait()`.
|
||||||
* TODO: expand
|
* TODO: expand
|
||||||
* [man page](http://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
|
* [man page][man epoll_ctl]
|
||||||
|
|
||||||
### epoll_wait
|
### epoll_wait
|
||||||
|
|
||||||
@ -108,8 +107,17 @@ int epoll_wait(HANDLE ephnd,
|
|||||||
* Receive socket events from an epoll port.
|
* Receive socket events from an epoll port.
|
||||||
* Returns
|
* Returns
|
||||||
- -1 on failure
|
- -1 on failure
|
||||||
- 0 when a timeout occurs
|
- 0 when a timeout occurs
|
||||||
- \>0 the number of evens received
|
- ≥1 the number of evens received
|
||||||
* TODO: expand
|
* TODO: expand
|
||||||
* [man page](http://man7.org/linux/man-pages/man2/epoll_wait.2.html)
|
* [man page][man epoll_wait]
|
||||||
|
|
||||||
|
[dist]: https://github.com/piscisaureus/wepoll/tree/dist
|
||||||
|
[man epoll]: http://man7.org/linux/man-pages/man7/epoll.7.html
|
||||||
|
[man epoll_create]: http://man7.org/linux/man-pages/man2/epoll_create.2.html
|
||||||
|
[man epoll_ctl]: http://man7.org/linux/man-pages/man2/epoll_ctl.2.html
|
||||||
|
[man epoll_wait]: http://man7.org/linux/man-pages/man2/epoll_wait.2.html
|
||||||
|
[select scale]: https://daniel.haxx.se/docs/poll-vs-select.html
|
||||||
|
[wsapoll broken]: https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/
|
||||||
|
[wepoll.c]: https://github.com/piscisaureus/wepoll/blob/dist/wepoll.c
|
||||||
|
[wepoll.h]: https://github.com/piscisaureus/wepoll/blob/dist/wepoll.h
|
||||||
|
|||||||
206
wepoll.c
206
wepoll.c
@ -35,38 +35,42 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
enum EPOLL_EVENTS {
|
enum EPOLL_EVENTS {
|
||||||
EPOLLIN = 1 << 0,
|
EPOLLIN = 1 << 0,
|
||||||
EPOLLPRI = 1 << 1,
|
EPOLLPRI = 1 << 1,
|
||||||
EPOLLOUT = 1 << 2,
|
EPOLLOUT = 1 << 2,
|
||||||
EPOLLERR = 1 << 3,
|
EPOLLERR = 1 << 3,
|
||||||
EPOLLHUP = 1 << 4,
|
EPOLLHUP = 1 << 4,
|
||||||
EPOLLRDNORM = 1 << 6,
|
EPOLLRDNORM = 1 << 6,
|
||||||
EPOLLRDBAND = 1 << 7,
|
EPOLLRDBAND = 1 << 7,
|
||||||
EPOLLWRNORM = 1 << 8,
|
EPOLLWRNORM = 1 << 8,
|
||||||
EPOLLWRBAND = 1 << 9,
|
EPOLLWRBAND = 1 << 9,
|
||||||
EPOLLMSG = 1 << 10,
|
EPOLLMSG = 1 << 10, /* Never reported. */
|
||||||
EPOLLRDHUP = 1 << 13,
|
EPOLLRDHUP = 1 << 13,
|
||||||
EPOLLONESHOT = 1 << 31
|
EPOLLONESHOT = 1 << 31
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EPOLLIN EPOLLIN
|
#define EPOLLIN ((uint32_t) EPOLLIN)
|
||||||
#define EPOLLPRI EPOLLPRI
|
#define EPOLLPRI ((uint32_t) EPOLLPRI)
|
||||||
#define EPOLLOUT EPOLLOUT
|
#define EPOLLOUT ((uint32_t) EPOLLOUT)
|
||||||
#define EPOLLERR EPOLLERR
|
#define EPOLLERR ((uint32_t) EPOLLERR)
|
||||||
#define EPOLLHUP EPOLLHUP
|
#define EPOLLHUP ((uint32_t) EPOLLHUP)
|
||||||
#define EPOLLRDNORM EPOLLRDNORM
|
#define EPOLLRDNORM ((uint32_t) EPOLLRDNORM)
|
||||||
#define EPOLLRDBAND EPOLLRDBAND
|
#define EPOLLRDBAND ((uint32_t) EPOLLRDBAND)
|
||||||
#define EPOLLWRNORM EPOLLWRNORM
|
#define EPOLLWRNORM ((uint32_t) EPOLLWRNORM)
|
||||||
#define EPOLLWRBAND EPOLLWRBAND
|
#define EPOLLWRBAND ((uint32_t) EPOLLWRBAND)
|
||||||
#define EPOLLMSG EPOLLMSG
|
#define EPOLLMSG ((uint32_t) EPOLLMSG)
|
||||||
#define EPOLLRDHUP EPOLLRDHUP
|
#define EPOLLRDHUP ((uint32_t) EPOLLRDHUP)
|
||||||
#define EPOLLONESHOT EPOLLONESHOT
|
#define EPOLLONESHOT ((uint32_t) EPOLLONESHOT)
|
||||||
|
|
||||||
#define EPOLL_CTL_ADD 1
|
#define EPOLL_CTL_ADD 1
|
||||||
#define EPOLL_CTL_MOD 2
|
#define EPOLL_CTL_MOD 2
|
||||||
#define EPOLL_CTL_DEL 3
|
#define EPOLL_CTL_DEL 3
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
typedef void* HANDLE;
|
typedef void* HANDLE;
|
||||||
typedef uintptr_t SOCKET;
|
typedef uintptr_t SOCKET;
|
||||||
|
|
||||||
@ -75,8 +79,8 @@ typedef union epoll_data {
|
|||||||
int fd;
|
int fd;
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
uint64_t u64;
|
uint64_t u64;
|
||||||
SOCKET sock;
|
SOCKET sock; /* Windows specific */
|
||||||
HANDLE hnd;
|
HANDLE hnd; /* Windows specific */
|
||||||
} epoll_data_t;
|
} epoll_data_t;
|
||||||
|
|
||||||
struct epoll_event {
|
struct epoll_event {
|
||||||
@ -118,6 +122,8 @@ WEPOLL_EXPORT int epoll_wait(HANDLE ephnd,
|
|||||||
#include <WinSock2.h>
|
#include <WinSock2.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
|
WEPOLL_INTERNAL int nt_global_init(void);
|
||||||
|
|
||||||
#ifndef _NTDEF_
|
#ifndef _NTDEF_
|
||||||
typedef LONG NTSTATUS;
|
typedef LONG NTSTATUS;
|
||||||
typedef NTSTATUS* PNTSTATUS;
|
typedef NTSTATUS* PNTSTATUS;
|
||||||
@ -187,6 +193,73 @@ typedef NTSTATUS* PNTSTATUS;
|
|||||||
#define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L)
|
#define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct _IO_STATUS_BLOCK {
|
||||||
|
union {
|
||||||
|
NTSTATUS Status;
|
||||||
|
PVOID Pointer;
|
||||||
|
};
|
||||||
|
ULONG_PTR Information;
|
||||||
|
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||||
|
|
||||||
|
typedef VOID(NTAPI* PIO_APC_ROUTINE)(PVOID ApcContext,
|
||||||
|
PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
|
ULONG Reserved);
|
||||||
|
|
||||||
|
typedef struct _LSA_UNICODE_STRING {
|
||||||
|
USHORT Length;
|
||||||
|
USHORT MaximumLength;
|
||||||
|
PWSTR Buffer;
|
||||||
|
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
|
||||||
|
|
||||||
|
typedef struct _OBJECT_ATTRIBUTES {
|
||||||
|
ULONG Length;
|
||||||
|
HANDLE RootDirectory;
|
||||||
|
PUNICODE_STRING ObjectName;
|
||||||
|
ULONG Attributes;
|
||||||
|
PVOID SecurityDescriptor;
|
||||||
|
PVOID SecurityQualityOfService;
|
||||||
|
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
|
||||||
|
|
||||||
|
#define NTDLL_IMPORT_LIST(X) \
|
||||||
|
X(NTSTATUS, \
|
||||||
|
NTAPI, \
|
||||||
|
NtDeviceIoControlFile, \
|
||||||
|
(HANDLE FileHandle, \
|
||||||
|
HANDLE Event, \
|
||||||
|
PIO_APC_ROUTINE ApcRoutine, \
|
||||||
|
PVOID ApcContext, \
|
||||||
|
PIO_STATUS_BLOCK IoStatusBlock, \
|
||||||
|
ULONG IoControlCode, \
|
||||||
|
PVOID InputBuffer, \
|
||||||
|
ULONG InputBufferLength, \
|
||||||
|
PVOID OutputBuffer, \
|
||||||
|
ULONG OutputBufferLength)) \
|
||||||
|
\
|
||||||
|
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status)) \
|
||||||
|
\
|
||||||
|
X(NTSTATUS, \
|
||||||
|
NTAPI, \
|
||||||
|
NtCreateKeyedEvent, \
|
||||||
|
(PHANDLE handle, \
|
||||||
|
ACCESS_MASK access, \
|
||||||
|
POBJECT_ATTRIBUTES attr, \
|
||||||
|
ULONG flags)) \
|
||||||
|
\
|
||||||
|
X(NTSTATUS, \
|
||||||
|
NTAPI, \
|
||||||
|
NtWaitForKeyedEvent, \
|
||||||
|
(HANDLE handle, PVOID key, BOOLEAN alertable, PLARGE_INTEGER mstimeout)) \
|
||||||
|
\
|
||||||
|
X(NTSTATUS, \
|
||||||
|
NTAPI, \
|
||||||
|
NtReleaseKeyedEvent, \
|
||||||
|
(HANDLE handle, PVOID key, BOOLEAN alertable, PLARGE_INTEGER mstimeout))
|
||||||
|
|
||||||
|
#define X(return_type, attributes, name, parameters) \
|
||||||
|
WEPOLL_INTERNAL_EXTERN return_type(attributes* name) parameters;
|
||||||
|
NTDLL_IMPORT_LIST(X)
|
||||||
|
#undef X
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifndef _SSIZE_T_DEFINED
|
#ifndef _SSIZE_T_DEFINED
|
||||||
@ -297,75 +370,6 @@ static const GUID AFD_PROVIDER_GUID_LIST[] = {
|
|||||||
WEPOLL_INTERNAL errno_t err_map_win_error_to_errno(DWORD error);
|
WEPOLL_INTERNAL errno_t err_map_win_error_to_errno(DWORD error);
|
||||||
WEPOLL_INTERNAL void err_set_win_error(DWORD error);
|
WEPOLL_INTERNAL void err_set_win_error(DWORD error);
|
||||||
|
|
||||||
WEPOLL_INTERNAL int nt_global_init(void);
|
|
||||||
|
|
||||||
typedef struct _IO_STATUS_BLOCK {
|
|
||||||
union {
|
|
||||||
NTSTATUS Status;
|
|
||||||
PVOID Pointer;
|
|
||||||
};
|
|
||||||
ULONG_PTR Information;
|
|
||||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
|
||||||
|
|
||||||
typedef VOID(NTAPI* PIO_APC_ROUTINE)(PVOID ApcContext,
|
|
||||||
PIO_STATUS_BLOCK IoStatusBlock,
|
|
||||||
ULONG Reserved);
|
|
||||||
|
|
||||||
typedef struct _LSA_UNICODE_STRING {
|
|
||||||
USHORT Length;
|
|
||||||
USHORT MaximumLength;
|
|
||||||
PWSTR Buffer;
|
|
||||||
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
|
|
||||||
|
|
||||||
typedef struct _OBJECT_ATTRIBUTES {
|
|
||||||
ULONG Length;
|
|
||||||
HANDLE RootDirectory;
|
|
||||||
PUNICODE_STRING ObjectName;
|
|
||||||
ULONG Attributes;
|
|
||||||
PVOID SecurityDescriptor;
|
|
||||||
PVOID SecurityQualityOfService;
|
|
||||||
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
|
|
||||||
|
|
||||||
#define NTDLL_IMPORT_LIST(X) \
|
|
||||||
X(NTSTATUS, \
|
|
||||||
NTAPI, \
|
|
||||||
NtDeviceIoControlFile, \
|
|
||||||
(HANDLE FileHandle, \
|
|
||||||
HANDLE Event, \
|
|
||||||
PIO_APC_ROUTINE ApcRoutine, \
|
|
||||||
PVOID ApcContext, \
|
|
||||||
PIO_STATUS_BLOCK IoStatusBlock, \
|
|
||||||
ULONG IoControlCode, \
|
|
||||||
PVOID InputBuffer, \
|
|
||||||
ULONG InputBufferLength, \
|
|
||||||
PVOID OutputBuffer, \
|
|
||||||
ULONG OutputBufferLength)) \
|
|
||||||
\
|
|
||||||
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status)) \
|
|
||||||
\
|
|
||||||
X(NTSTATUS, \
|
|
||||||
NTAPI, \
|
|
||||||
NtCreateKeyedEvent, \
|
|
||||||
(PHANDLE handle, \
|
|
||||||
ACCESS_MASK access, \
|
|
||||||
POBJECT_ATTRIBUTES attr, \
|
|
||||||
ULONG flags)) \
|
|
||||||
\
|
|
||||||
X(NTSTATUS, \
|
|
||||||
NTAPI, \
|
|
||||||
NtWaitForKeyedEvent, \
|
|
||||||
(HANDLE handle, PVOID key, BOOLEAN alertable, PLARGE_INTEGER mstimeout)) \
|
|
||||||
\
|
|
||||||
X(NTSTATUS, \
|
|
||||||
NTAPI, \
|
|
||||||
NtReleaseKeyedEvent, \
|
|
||||||
(HANDLE handle, PVOID key, BOOLEAN alertable, PLARGE_INTEGER mstimeout))
|
|
||||||
|
|
||||||
#define X(return_type, attributes, name, parameters) \
|
|
||||||
WEPOLL_INTERNAL_EXTERN return_type(attributes* name) parameters;
|
|
||||||
NTDLL_IMPORT_LIST(X)
|
|
||||||
#undef X
|
|
||||||
|
|
||||||
#define FILE_DEVICE_NETWORK 0x00000012
|
#define FILE_DEVICE_NETWORK 0x00000012
|
||||||
#define METHOD_BUFFERED 0
|
#define METHOD_BUFFERED 0
|
||||||
#define AFD_POLL 9
|
#define AFD_POLL 9
|
||||||
@ -2073,7 +2077,7 @@ reflock_tree_node_t* reflock_tree_del_and_ref(reflock_tree_t* rlt,
|
|||||||
|
|
||||||
AcquireSRWLockExclusive(&rlt->lock);
|
AcquireSRWLockExclusive(&rlt->lock);
|
||||||
|
|
||||||
tree_node = tree_find(&rlt->tree, (uintptr_t) key);
|
tree_node = tree_find(&rlt->tree, key);
|
||||||
rlt_node = safe_container_of(tree_node, reflock_tree_node_t, tree_node);
|
rlt_node = safe_container_of(tree_node, reflock_tree_node_t, tree_node);
|
||||||
|
|
||||||
if (rlt_node != NULL) {
|
if (rlt_node != NULL) {
|
||||||
@ -2093,7 +2097,7 @@ reflock_tree_node_t* reflock_tree_find_and_ref(reflock_tree_t* rlt,
|
|||||||
|
|
||||||
AcquireSRWLockShared(&rlt->lock);
|
AcquireSRWLockShared(&rlt->lock);
|
||||||
|
|
||||||
tree_node = tree_find(&rlt->tree, (uintptr_t) key);
|
tree_node = tree_find(&rlt->tree, key);
|
||||||
rlt_node = safe_container_of(tree_node, reflock_tree_node_t, tree_node);
|
rlt_node = safe_container_of(tree_node, reflock_tree_node_t, tree_node);
|
||||||
if (rlt_node != NULL)
|
if (rlt_node != NULL)
|
||||||
reflock_ref(&rlt_node->reflock);
|
reflock_ref(&rlt_node->reflock);
|
||||||
@ -2199,7 +2203,9 @@ void reflock_unref_and_destroy(reflock_t* reflock) {
|
|||||||
assert(state == _DESTROY);
|
assert(state == _DESTROY);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _EP_EVENT_MASK 0xffff
|
#define _KNOWN_EPOLL_EVENTS \
|
||||||
|
(EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDNORM | \
|
||||||
|
EPOLLRDBAND | EPOLLWRNORM | EPOLLWRBAND | EPOLLRDHUP)
|
||||||
|
|
||||||
typedef struct _poll_req {
|
typedef struct _poll_req {
|
||||||
OVERLAPPED overlapped;
|
OVERLAPPED overlapped;
|
||||||
@ -2433,7 +2439,7 @@ int ep_sock_set_event(ep_port_t* port_info,
|
|||||||
sock_private->user_events = events;
|
sock_private->user_events = events;
|
||||||
sock_private->user_data = ev->data;
|
sock_private->user_data = ev->data;
|
||||||
|
|
||||||
if ((events & _EP_EVENT_MASK & ~(sock_private->pending_events)) != 0)
|
if ((events & _KNOWN_EPOLL_EVENTS & ~sock_private->pending_events) != 0)
|
||||||
ep_port_request_socket_update(port_info, sock_info);
|
ep_port_request_socket_update(port_info, sock_info);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2446,8 +2452,8 @@ int ep_sock_update(ep_port_t* port_info, ep_sock_t* sock_info) {
|
|||||||
|
|
||||||
assert(ep_port_is_socket_update_pending(port_info, sock_info));
|
assert(ep_port_is_socket_update_pending(port_info, sock_info));
|
||||||
|
|
||||||
if (sock_private->poll_status == _POLL_PENDING &&
|
if ((sock_private->poll_status == _POLL_PENDING) &&
|
||||||
(sock_private->user_events & _EP_EVENT_MASK &
|
(sock_private->user_events & _KNOWN_EPOLL_EVENTS &
|
||||||
~sock_private->pending_events) == 0) {
|
~sock_private->pending_events) == 0) {
|
||||||
/* All the events the user is interested in are already being monitored
|
/* All the events the user is interested in are already being monitored
|
||||||
* by the pending poll request. It might spuriously complete because of an
|
* by the pending poll request. It might spuriously complete because of an
|
||||||
|
|||||||
54
wepoll.h
54
wepoll.h
@ -38,38 +38,42 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
enum EPOLL_EVENTS {
|
enum EPOLL_EVENTS {
|
||||||
EPOLLIN = 1 << 0,
|
EPOLLIN = 1 << 0,
|
||||||
EPOLLPRI = 1 << 1,
|
EPOLLPRI = 1 << 1,
|
||||||
EPOLLOUT = 1 << 2,
|
EPOLLOUT = 1 << 2,
|
||||||
EPOLLERR = 1 << 3,
|
EPOLLERR = 1 << 3,
|
||||||
EPOLLHUP = 1 << 4,
|
EPOLLHUP = 1 << 4,
|
||||||
EPOLLRDNORM = 1 << 6,
|
EPOLLRDNORM = 1 << 6,
|
||||||
EPOLLRDBAND = 1 << 7,
|
EPOLLRDBAND = 1 << 7,
|
||||||
EPOLLWRNORM = 1 << 8,
|
EPOLLWRNORM = 1 << 8,
|
||||||
EPOLLWRBAND = 1 << 9,
|
EPOLLWRBAND = 1 << 9,
|
||||||
EPOLLMSG = 1 << 10,
|
EPOLLMSG = 1 << 10, /* Never reported. */
|
||||||
EPOLLRDHUP = 1 << 13,
|
EPOLLRDHUP = 1 << 13,
|
||||||
EPOLLONESHOT = 1 << 31
|
EPOLLONESHOT = 1 << 31
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EPOLLIN EPOLLIN
|
#define EPOLLIN ((uint32_t) EPOLLIN)
|
||||||
#define EPOLLPRI EPOLLPRI
|
#define EPOLLPRI ((uint32_t) EPOLLPRI)
|
||||||
#define EPOLLOUT EPOLLOUT
|
#define EPOLLOUT ((uint32_t) EPOLLOUT)
|
||||||
#define EPOLLERR EPOLLERR
|
#define EPOLLERR ((uint32_t) EPOLLERR)
|
||||||
#define EPOLLHUP EPOLLHUP
|
#define EPOLLHUP ((uint32_t) EPOLLHUP)
|
||||||
#define EPOLLRDNORM EPOLLRDNORM
|
#define EPOLLRDNORM ((uint32_t) EPOLLRDNORM)
|
||||||
#define EPOLLRDBAND EPOLLRDBAND
|
#define EPOLLRDBAND ((uint32_t) EPOLLRDBAND)
|
||||||
#define EPOLLWRNORM EPOLLWRNORM
|
#define EPOLLWRNORM ((uint32_t) EPOLLWRNORM)
|
||||||
#define EPOLLWRBAND EPOLLWRBAND
|
#define EPOLLWRBAND ((uint32_t) EPOLLWRBAND)
|
||||||
#define EPOLLMSG EPOLLMSG
|
#define EPOLLMSG ((uint32_t) EPOLLMSG)
|
||||||
#define EPOLLRDHUP EPOLLRDHUP
|
#define EPOLLRDHUP ((uint32_t) EPOLLRDHUP)
|
||||||
#define EPOLLONESHOT EPOLLONESHOT
|
#define EPOLLONESHOT ((uint32_t) EPOLLONESHOT)
|
||||||
|
|
||||||
#define EPOLL_CTL_ADD 1
|
#define EPOLL_CTL_ADD 1
|
||||||
#define EPOLL_CTL_MOD 2
|
#define EPOLL_CTL_MOD 2
|
||||||
#define EPOLL_CTL_DEL 3
|
#define EPOLL_CTL_DEL 3
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
typedef void* HANDLE;
|
typedef void* HANDLE;
|
||||||
typedef uintptr_t SOCKET;
|
typedef uintptr_t SOCKET;
|
||||||
|
|
||||||
@ -78,8 +82,8 @@ typedef union epoll_data {
|
|||||||
int fd;
|
int fd;
|
||||||
uint32_t u32;
|
uint32_t u32;
|
||||||
uint64_t u64;
|
uint64_t u64;
|
||||||
SOCKET sock;
|
SOCKET sock; /* Windows specific */
|
||||||
HANDLE hnd;
|
HANDLE hnd; /* Windows specific */
|
||||||
} epoll_data_t;
|
} epoll_data_t;
|
||||||
|
|
||||||
struct epoll_event {
|
struct epoll_event {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user