version 1.5.5
This commit is contained in:
commit
e9bf27c395
2
LICENSE
2
LICENSE
@ -1,7 +1,7 @@
|
|||||||
wepoll - epoll for Windows
|
wepoll - epoll for Windows
|
||||||
https://github.com/piscisaureus/wepoll
|
https://github.com/piscisaureus/wepoll
|
||||||
|
|
||||||
Copyright 2012-2018, Bert Belder <bertbelder@gmail.com>
|
Copyright 2012-2019, Bert Belder <bertbelder@gmail.com>
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
77
wepoll.c
77
wepoll.c
@ -2,7 +2,7 @@
|
|||||||
* wepoll - epoll for Windows
|
* wepoll - epoll for Windows
|
||||||
* https://github.com/piscisaureus/wepoll
|
* https://github.com/piscisaureus/wepoll
|
||||||
*
|
*
|
||||||
* Copyright 2012-2018, Bert Belder <bertbelder@gmail.com>
|
* Copyright 2012-2019, Bert Belder <bertbelder@gmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -35,8 +35,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
enum EPOLL_EVENTS {
|
enum EPOLL_EVENTS {
|
||||||
EPOLLIN = (int) (1U << 0),
|
EPOLLIN = (int) (1U << 0),
|
||||||
EPOLLPRI = (int) (1U << 1),
|
EPOLLPRI = (int) (1U << 1),
|
||||||
@ -69,8 +67,6 @@ enum EPOLL_EVENTS {
|
|||||||
#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;
|
||||||
|
|
||||||
@ -178,11 +174,11 @@ typedef VOID(NTAPI* PIO_APC_ROUTINE)(PVOID ApcContext,
|
|||||||
PIO_STATUS_BLOCK IoStatusBlock,
|
PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
ULONG Reserved);
|
ULONG Reserved);
|
||||||
|
|
||||||
typedef struct _LSA_UNICODE_STRING {
|
typedef struct _UNICODE_STRING {
|
||||||
USHORT Length;
|
USHORT Length;
|
||||||
USHORT MaximumLength;
|
USHORT MaximumLength;
|
||||||
PWSTR Buffer;
|
PWSTR Buffer;
|
||||||
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
|
} UNICODE_STRING, *PUNICODE_STRING;
|
||||||
|
|
||||||
#define RTL_CONSTANT_STRING(s) \
|
#define RTL_CONSTANT_STRING(s) \
|
||||||
{ sizeof(s) - sizeof((s)[0]), sizeof(s), s }
|
{ sizeof(s) - sizeof((s)[0]), sizeof(s), s }
|
||||||
@ -203,6 +199,11 @@ typedef struct _OBJECT_ATTRIBUTES {
|
|||||||
#define FILE_OPEN 0x00000001UL
|
#define FILE_OPEN 0x00000001UL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define KEYEDEVENT_WAIT 0x00000001UL
|
||||||
|
#define KEYEDEVENT_WAKE 0x00000002UL
|
||||||
|
#define KEYEDEVENT_ALL_ACCESS \
|
||||||
|
(STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE)
|
||||||
|
|
||||||
#define NT_NTDLL_IMPORT_LIST(X) \
|
#define NT_NTDLL_IMPORT_LIST(X) \
|
||||||
X(NTSTATUS, \
|
X(NTSTATUS, \
|
||||||
NTAPI, \
|
NTAPI, \
|
||||||
@ -219,6 +220,14 @@ typedef struct _OBJECT_ATTRIBUTES {
|
|||||||
PVOID EaBuffer, \
|
PVOID EaBuffer, \
|
||||||
ULONG EaLength)) \
|
ULONG EaLength)) \
|
||||||
\
|
\
|
||||||
|
X(NTSTATUS, \
|
||||||
|
NTAPI, \
|
||||||
|
NtCreateKeyedEvent, \
|
||||||
|
(PHANDLE KeyedEventHandle, \
|
||||||
|
ACCESS_MASK DesiredAccess, \
|
||||||
|
POBJECT_ATTRIBUTES ObjectAttributes, \
|
||||||
|
ULONG Flags)) \
|
||||||
|
\
|
||||||
X(NTSTATUS, \
|
X(NTSTATUS, \
|
||||||
NTAPI, \
|
NTAPI, \
|
||||||
NtDeviceIoControlFile, \
|
NtDeviceIoControlFile, \
|
||||||
@ -233,25 +242,23 @@ typedef struct _OBJECT_ATTRIBUTES {
|
|||||||
PVOID OutputBuffer, \
|
PVOID OutputBuffer, \
|
||||||
ULONG OutputBufferLength)) \
|
ULONG OutputBufferLength)) \
|
||||||
\
|
\
|
||||||
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status)) \
|
|
||||||
\
|
|
||||||
X(NTSTATUS, \
|
X(NTSTATUS, \
|
||||||
NTAPI, \
|
NTAPI, \
|
||||||
NtCreateKeyedEvent, \
|
NtReleaseKeyedEvent, \
|
||||||
(PHANDLE handle, \
|
(HANDLE KeyedEventHandle, \
|
||||||
ACCESS_MASK access, \
|
PVOID KeyValue, \
|
||||||
POBJECT_ATTRIBUTES attr, \
|
BOOLEAN Alertable, \
|
||||||
ULONG flags)) \
|
PLARGE_INTEGER Timeout)) \
|
||||||
\
|
\
|
||||||
X(NTSTATUS, \
|
X(NTSTATUS, \
|
||||||
NTAPI, \
|
NTAPI, \
|
||||||
NtWaitForKeyedEvent, \
|
NtWaitForKeyedEvent, \
|
||||||
(HANDLE handle, PVOID key, BOOLEAN alertable, PLARGE_INTEGER mstimeout)) \
|
(HANDLE KeyedEventHandle, \
|
||||||
|
PVOID KeyValue, \
|
||||||
|
BOOLEAN Alertable, \
|
||||||
|
PLARGE_INTEGER Timeout)) \
|
||||||
\
|
\
|
||||||
X(NTSTATUS, \
|
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status))
|
||||||
NTAPI, \
|
|
||||||
NtReleaseKeyedEvent, \
|
|
||||||
(HANDLE handle, PVOID key, BOOLEAN alertable, PLARGE_INTEGER mstimeout))
|
|
||||||
|
|
||||||
#define X(return_type, attributes, name, parameters) \
|
#define X(return_type, attributes, name, parameters) \
|
||||||
WEPOLL_INTERNAL_VAR return_type(attributes* name) parameters;
|
WEPOLL_INTERNAL_VAR return_type(attributes* name) parameters;
|
||||||
@ -267,10 +274,8 @@ typedef intptr_t ssize_t;
|
|||||||
|
|
||||||
#define array_count(a) (sizeof(a) / (sizeof((a)[0])))
|
#define array_count(a) (sizeof(a) / (sizeof((a)[0])))
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
#define container_of(ptr, type, member) \
|
#define container_of(ptr, type, member) \
|
||||||
((type*) ((uintptr_t) (ptr) - offsetof(type, member)))
|
((type*) ((uintptr_t) (ptr) - offsetof(type, member)))
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
#define unused_var(v) ((void) (v))
|
#define unused_var(v) ((void) (v))
|
||||||
|
|
||||||
@ -279,7 +284,6 @@ typedef intptr_t ssize_t;
|
|||||||
#define inline __inline
|
#define inline __inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
#define AFD_POLL_RECEIVE 0x0001
|
#define AFD_POLL_RECEIVE 0x0001
|
||||||
#define AFD_POLL_RECEIVE_EXPEDITED 0x0002
|
#define AFD_POLL_RECEIVE_EXPEDITED 0x0002
|
||||||
#define AFD_POLL_SEND 0x0004
|
#define AFD_POLL_SEND 0x0004
|
||||||
@ -288,7 +292,6 @@ typedef intptr_t ssize_t;
|
|||||||
#define AFD_POLL_LOCAL_CLOSE 0x0020
|
#define AFD_POLL_LOCAL_CLOSE 0x0020
|
||||||
#define AFD_POLL_ACCEPT 0x0080
|
#define AFD_POLL_ACCEPT 0x0080
|
||||||
#define AFD_POLL_CONNECT_FAIL 0x0100
|
#define AFD_POLL_CONNECT_FAIL 0x0100
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
typedef struct _AFD_POLL_HANDLE_INFO {
|
typedef struct _AFD_POLL_HANDLE_INFO {
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
@ -919,7 +922,11 @@ static BOOL CALLBACK init__once_callback(INIT_ONCE* once,
|
|||||||
int init(void) {
|
int init(void) {
|
||||||
if (!init__done &&
|
if (!init__done &&
|
||||||
!InitOnceExecuteOnce(&init__once, init__once_callback, NULL, NULL))
|
!InitOnceExecuteOnce(&init__once, init__once_callback, NULL, NULL))
|
||||||
return -1; /* LastError and errno aren't touched InitOnceExecuteOnce. */
|
/* `InitOnceExecuteOnce()` itself is infallible, and it doesn't set any
|
||||||
|
* error code when the once-callback returns FALSE. We return -1 here to
|
||||||
|
* indicate that global initialization failed; the failing init function is
|
||||||
|
* resposible for setting `errno` and calling `SetLastError()`. */
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1476,19 +1483,17 @@ bool queue_enqueued(const queue_node_t* node) {
|
|||||||
return node->prev != node;
|
return node->prev != node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
static const long REFLOCK__REF = (long) 0x00000001;
|
static const long REFLOCK__REF = (long) 0x00000001;
|
||||||
static const long REFLOCK__REF_MASK = (long) 0x0fffffff;
|
static const long REFLOCK__REF_MASK = (long) 0x0fffffff;
|
||||||
static const long REFLOCK__DESTROY = (long) 0x10000000;
|
static const long REFLOCK__DESTROY = (long) 0x10000000;
|
||||||
static const long REFLOCK__DESTROY_MASK = (long) 0xf0000000;
|
static const long REFLOCK__DESTROY_MASK = (long) 0xf0000000;
|
||||||
static const long REFLOCK__POISON = (long) 0x300DEAD0;
|
static const long REFLOCK__POISON = (long) 0x300dead0;
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
static HANDLE reflock__keyed_event = NULL;
|
static HANDLE reflock__keyed_event = NULL;
|
||||||
|
|
||||||
int reflock_global_init(void) {
|
int reflock_global_init(void) {
|
||||||
NTSTATUS status =
|
NTSTATUS status =
|
||||||
NtCreateKeyedEvent(&reflock__keyed_event, ~(ACCESS_MASK) 0, NULL, 0);
|
NtCreateKeyedEvent(&reflock__keyed_event, KEYEDEVENT_ALL_ACCESS, NULL, 0);
|
||||||
if (status != STATUS_SUCCESS)
|
if (status != STATUS_SUCCESS)
|
||||||
return_set_error(-1, RtlNtStatusToDosError(status));
|
return_set_error(-1, RtlNtStatusToDosError(status));
|
||||||
return 0;
|
return 0;
|
||||||
@ -1514,22 +1519,20 @@ static void reflock__await_event(void* address) {
|
|||||||
|
|
||||||
void reflock_ref(reflock_t* reflock) {
|
void reflock_ref(reflock_t* reflock) {
|
||||||
long state = InterlockedAdd(&reflock->state, REFLOCK__REF);
|
long state = InterlockedAdd(&reflock->state, REFLOCK__REF);
|
||||||
|
|
||||||
|
/* Verify that the counter didn't overflow and the lock isn't destroyed. */
|
||||||
|
assert((state & REFLOCK__DESTROY_MASK) == 0);
|
||||||
unused_var(state);
|
unused_var(state);
|
||||||
assert((state & REFLOCK__DESTROY_MASK) == 0); /* Overflow or destroyed. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reflock_unref(reflock_t* reflock) {
|
void reflock_unref(reflock_t* reflock) {
|
||||||
long state = InterlockedAdd(&reflock->state, -REFLOCK__REF);
|
long state = InterlockedAdd(&reflock->state, -REFLOCK__REF);
|
||||||
long ref_count = state & REFLOCK__REF_MASK;
|
|
||||||
long destroy = state & REFLOCK__DESTROY_MASK;
|
|
||||||
|
|
||||||
unused_var(ref_count);
|
/* Verify that the lock was referenced and not already destroyed. */
|
||||||
unused_var(destroy);
|
assert((state & REFLOCK__DESTROY_MASK & ~REFLOCK__DESTROY) == 0);
|
||||||
|
|
||||||
if (state == REFLOCK__DESTROY)
|
if (state == REFLOCK__DESTROY)
|
||||||
reflock__signal_event(reflock);
|
reflock__signal_event(reflock);
|
||||||
else
|
|
||||||
assert(destroy == 0 || ref_count > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reflock_unref_and_destroy(reflock_t* reflock) {
|
void reflock_unref_and_destroy(reflock_t* reflock) {
|
||||||
@ -1537,8 +1540,8 @@ void reflock_unref_and_destroy(reflock_t* reflock) {
|
|||||||
InterlockedAdd(&reflock->state, REFLOCK__DESTROY - REFLOCK__REF);
|
InterlockedAdd(&reflock->state, REFLOCK__DESTROY - REFLOCK__REF);
|
||||||
long ref_count = state & REFLOCK__REF_MASK;
|
long ref_count = state & REFLOCK__REF_MASK;
|
||||||
|
|
||||||
assert((state & REFLOCK__DESTROY_MASK) ==
|
/* Verify that the lock was referenced and not already destroyed. */
|
||||||
REFLOCK__DESTROY); /* Underflow or already destroyed. */
|
assert((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY);
|
||||||
|
|
||||||
if (ref_count != 0)
|
if (ref_count != 0)
|
||||||
reflock__await_event(reflock);
|
reflock__await_event(reflock);
|
||||||
|
|||||||
6
wepoll.h
6
wepoll.h
@ -2,7 +2,7 @@
|
|||||||
* wepoll - epoll for Windows
|
* wepoll - epoll for Windows
|
||||||
* https://github.com/piscisaureus/wepoll
|
* https://github.com/piscisaureus/wepoll
|
||||||
*
|
*
|
||||||
* Copyright 2012-2018, Bert Belder <bertbelder@gmail.com>
|
* Copyright 2012-2019, Bert Belder <bertbelder@gmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -38,8 +38,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
enum EPOLL_EVENTS {
|
enum EPOLL_EVENTS {
|
||||||
EPOLLIN = (int) (1U << 0),
|
EPOLLIN = (int) (1U << 0),
|
||||||
EPOLLPRI = (int) (1U << 1),
|
EPOLLPRI = (int) (1U << 1),
|
||||||
@ -72,8 +70,6 @@ enum EPOLL_EVENTS {
|
|||||||
#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;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user