version 1.5.5

This commit is contained in:
Bert Belder 2019-05-05 05:14:52 +02:00
commit e9bf27c395
No known key found for this signature in database
GPG Key ID: 7A77887B2E2ED461
3 changed files with 79 additions and 80 deletions

View File

@ -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

151
wepoll.c
View File

@ -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,55 +199,66 @@ typedef struct _OBJECT_ATTRIBUTES {
#define FILE_OPEN 0x00000001UL #define FILE_OPEN 0x00000001UL
#endif #endif
#define NT_NTDLL_IMPORT_LIST(X) \ #define KEYEDEVENT_WAIT 0x00000001UL
X(NTSTATUS, \ #define KEYEDEVENT_WAKE 0x00000002UL
NTAPI, \ #define KEYEDEVENT_ALL_ACCESS \
NtCreateFile, \ (STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE)
(PHANDLE FileHandle, \
ACCESS_MASK DesiredAccess, \ #define NT_NTDLL_IMPORT_LIST(X) \
POBJECT_ATTRIBUTES ObjectAttributes, \ X(NTSTATUS, \
PIO_STATUS_BLOCK IoStatusBlock, \ NTAPI, \
PLARGE_INTEGER AllocationSize, \ NtCreateFile, \
ULONG FileAttributes, \ (PHANDLE FileHandle, \
ULONG ShareAccess, \ ACCESS_MASK DesiredAccess, \
ULONG CreateDisposition, \ POBJECT_ATTRIBUTES ObjectAttributes, \
ULONG CreateOptions, \ PIO_STATUS_BLOCK IoStatusBlock, \
PVOID EaBuffer, \ PLARGE_INTEGER AllocationSize, \
ULONG EaLength)) \ ULONG FileAttributes, \
\ ULONG ShareAccess, \
X(NTSTATUS, \ ULONG CreateDisposition, \
NTAPI, \ ULONG CreateOptions, \
NtDeviceIoControlFile, \ PVOID EaBuffer, \
(HANDLE FileHandle, \ ULONG EaLength)) \
HANDLE Event, \ \
PIO_APC_ROUTINE ApcRoutine, \ X(NTSTATUS, \
PVOID ApcContext, \ NTAPI, \
PIO_STATUS_BLOCK IoStatusBlock, \ NtCreateKeyedEvent, \
ULONG IoControlCode, \ (PHANDLE KeyedEventHandle, \
PVOID InputBuffer, \ ACCESS_MASK DesiredAccess, \
ULONG InputBufferLength, \ POBJECT_ATTRIBUTES ObjectAttributes, \
PVOID OutputBuffer, \ ULONG Flags)) \
ULONG OutputBufferLength)) \ \
\ X(NTSTATUS, \
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status)) \ NTAPI, \
\ NtDeviceIoControlFile, \
X(NTSTATUS, \ (HANDLE FileHandle, \
NTAPI, \ HANDLE Event, \
NtCreateKeyedEvent, \ PIO_APC_ROUTINE ApcRoutine, \
(PHANDLE handle, \ PVOID ApcContext, \
ACCESS_MASK access, \ PIO_STATUS_BLOCK IoStatusBlock, \
POBJECT_ATTRIBUTES attr, \ ULONG IoControlCode, \
ULONG flags)) \ PVOID InputBuffer, \
\ ULONG InputBufferLength, \
X(NTSTATUS, \ PVOID OutputBuffer, \
NTAPI, \ ULONG OutputBufferLength)) \
NtWaitForKeyedEvent, \ \
(HANDLE handle, PVOID key, BOOLEAN alertable, PLARGE_INTEGER mstimeout)) \ X(NTSTATUS, \
\ NTAPI, \
X(NTSTATUS, \ NtReleaseKeyedEvent, \
NTAPI, \ (HANDLE KeyedEventHandle, \
NtReleaseKeyedEvent, \ PVOID KeyValue, \
(HANDLE handle, PVOID key, BOOLEAN alertable, PLARGE_INTEGER mstimeout)) BOOLEAN Alertable, \
PLARGE_INTEGER Timeout)) \
\
X(NTSTATUS, \
NTAPI, \
NtWaitForKeyedEvent, \
(HANDLE KeyedEventHandle, \
PVOID KeyValue, \
BOOLEAN Alertable, \
PLARGE_INTEGER Timeout)) \
\
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status))
#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);

View File

@ -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;