-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: APIScan reports Documentation Not Found errors (#33)
Patches wepoll to use conditional variables instead of keyed event Windows APIs.
- Loading branch information
Showing
7 changed files
with
209 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
diff --git a/external/wepoll/wepoll.c b/external/wepoll/wepoll.c | ||
index 186d3f2d..d440eeb8 100644 | ||
--- a/external/wepoll/wepoll.c | ||
+++ b/external/wepoll/wepoll.c | ||
@@ -197,11 +197,6 @@ typedef struct _OBJECT_ATTRIBUTES { | ||
#define FILE_OPEN 0x00000001UL | ||
#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) \ | ||
X(NTSTATUS, \ | ||
NTAPI, \ | ||
@@ -225,14 +220,6 @@ typedef struct _OBJECT_ATTRIBUTES { | ||
PVOID EaBuffer, \ | ||
ULONG EaLength)) \ | ||
\ | ||
- X(NTSTATUS, \ | ||
- NTAPI, \ | ||
- NtCreateKeyedEvent, \ | ||
- (PHANDLE KeyedEventHandle, \ | ||
- ACCESS_MASK DesiredAccess, \ | ||
- POBJECT_ATTRIBUTES ObjectAttributes, \ | ||
- ULONG Flags)) \ | ||
- \ | ||
X(NTSTATUS, \ | ||
NTAPI, \ | ||
NtDeviceIoControlFile, \ | ||
@@ -247,22 +234,6 @@ typedef struct _OBJECT_ATTRIBUTES { | ||
PVOID OutputBuffer, \ | ||
ULONG OutputBufferLength)) \ | ||
\ | ||
- X(NTSTATUS, \ | ||
- NTAPI, \ | ||
- NtReleaseKeyedEvent, \ | ||
- (HANDLE KeyedEventHandle, \ | ||
- PVOID KeyValue, \ | ||
- 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) \ | ||
@@ -481,6 +452,8 @@ WEPOLL_INTERNAL ts_tree_node_t* port_state_to_handle_tree_node( | ||
|
||
typedef struct reflock { | ||
volatile long state; /* 32-bit Interlocked APIs operate on `long` values. */ | ||
+ CONDITION_VARIABLE cv_signal; | ||
+ CONDITION_VARIABLE cv_await; | ||
} reflock_t; | ||
|
||
WEPOLL_INTERNAL int reflock_global_init(void); | ||
@@ -1520,35 +1493,60 @@ bool queue_is_enqueued(const queue_node_t* node) { | ||
#define REFLOCK__REF ((long) 0x00000001UL) | ||
#define REFLOCK__REF_MASK ((long) 0x0fffffffUL) | ||
#define REFLOCK__DESTROY ((long) 0x10000000UL) | ||
-#define REFLOCK__DESTROY_MASK ((long) 0xf0000000UL) | ||
-#define REFLOCK__POISON ((long) 0x300dead0UL) | ||
+#define REFLOCK__DESTROY_MASK ((long) 0x10000000UL) | ||
+#define REFLOCK__SIGNAL ((long) 0x20000000UL) | ||
+#define REFLOCK__SIGNAL_MASK ((long) 0x20000000UL) | ||
+#define REFLOCK__AWAIT ((long) 0x40000000UL) | ||
+#define REFLOCK__AWAIT_MASK ((long) 0x40000000UL) | ||
+#define REFLOCK__POISON ((long) 0x800dead0UL) | ||
|
||
-static HANDLE reflock__keyed_event = NULL; | ||
+static CRITICAL_SECTION signalMutex; | ||
|
||
int reflock_global_init(void) { | ||
- NTSTATUS status = NtCreateKeyedEvent( | ||
- &reflock__keyed_event, KEYEDEVENT_ALL_ACCESS, NULL, 0); | ||
- if (status != STATUS_SUCCESS) | ||
- return_set_error(-1, RtlNtStatusToDosError(status)); | ||
+ InitializeCriticalSection(&signalMutex); | ||
return 0; | ||
} | ||
|
||
void reflock_init(reflock_t* reflock) { | ||
reflock->state = 0; | ||
+ InitializeConditionVariable(&reflock->cv_signal); | ||
+ InitializeConditionVariable(&reflock->cv_await); | ||
} | ||
|
||
-static void reflock__signal_event(void* address) { | ||
- NTSTATUS status = | ||
- NtReleaseKeyedEvent(reflock__keyed_event, address, FALSE, NULL); | ||
- if (status != STATUS_SUCCESS) | ||
+static void reflock__signal_event(reflock_t* reflock) { | ||
+ BOOL status = TRUE; | ||
+ | ||
+ EnterCriticalSection(&signalMutex); | ||
+ long state = InterlockedOr(&reflock->state, REFLOCK__SIGNAL); | ||
+ while ((reflock->state & REFLOCK__AWAIT_MASK) == 0) { | ||
+ status = SleepConditionVariableCS(&reflock->cv_signal, &signalMutex, INFINITE); | ||
+ } | ||
+ LeaveCriticalSection(&signalMutex); | ||
+ | ||
+ if (status != TRUE) | ||
abort(); | ||
+ | ||
+ /* At most one reflock__await_event call per reflock. */ | ||
+ WakeConditionVariable(&reflock->cv_await); | ||
+ unused_var(state); | ||
} | ||
|
||
-static void reflock__await_event(void* address) { | ||
- NTSTATUS status = | ||
- NtWaitForKeyedEvent(reflock__keyed_event, address, FALSE, NULL); | ||
- if (status != STATUS_SUCCESS) | ||
+static void reflock__await_event(reflock_t* reflock) { | ||
+ BOOL status = TRUE; | ||
+ | ||
+ EnterCriticalSection(&signalMutex); | ||
+ long state = InterlockedOr(&reflock->state, REFLOCK__AWAIT); | ||
+ while ((reflock->state & REFLOCK__SIGNAL_MASK) == 0) { | ||
+ status = SleepConditionVariableCS(&reflock->cv_await, &signalMutex, INFINITE); | ||
+ } | ||
+ LeaveCriticalSection(&signalMutex); | ||
+ | ||
+ if (status != TRUE) | ||
abort(); | ||
+ | ||
+ /* Multiple threads could be waiting. */ | ||
+ WakeAllConditionVariable(&reflock->cv_signal); | ||
+ unused_var(state); | ||
} | ||
|
||
void reflock_ref(reflock_t* reflock) { | ||
@@ -1565,7 +1563,8 @@ void reflock_unref(reflock_t* reflock) { | ||
/* Verify that the lock was referenced and not already destroyed. */ | ||
assert((state & REFLOCK__DESTROY_MASK & ~REFLOCK__DESTROY) == 0); | ||
|
||
- if (state == REFLOCK__DESTROY) | ||
+ if ((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY && | ||
+ (state & REFLOCK__REF_MASK) == 0) | ||
reflock__signal_event(reflock); | ||
} | ||
|
||
@@ -1581,7 +1580,8 @@ void reflock_unref_and_destroy(reflock_t* reflock) { | ||
reflock__await_event(reflock); | ||
|
||
state = InterlockedExchange(&reflock->state, REFLOCK__POISON); | ||
- assert(state == REFLOCK__DESTROY); | ||
+ assert((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY); | ||
+ assert((state & REFLOCK__REF_MASK) == 0); | ||
} | ||
|
||
#define SOCK__KNOWN_EPOLL_EVENTS \ |
Oops, something went wrong.