aboutsummaryrefslogtreecommitdiff
path: root/core/sync
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-08-17 13:12:45 +0100
committergingerBill <bill@gingerbill.org>2022-08-17 13:12:45 +0100
commit82765ca96e90f8ca3d2870e1b00bba3fecc0a78f (patch)
treee21d92ed7b0e304b0c82126dd5562e51fea5b8e5 /core/sync
parentf2908cbc5aaec9c0472f1546f095eb4982a80232 (diff)
Fix `RtlWaitOnAddress` behaviour with `SetLastError(RtlNtStatusToDosError(status))` if an error occurred
Diffstat (limited to 'core/sync')
-rw-r--r--core/sync/futex_windows.odin26
1 files changed, 24 insertions, 2 deletions
diff --git a/core/sync/futex_windows.odin b/core/sync/futex_windows.odin
index ce662ba9e..ba6292742 100644
--- a/core/sync/futex_windows.odin
+++ b/core/sync/futex_windows.odin
@@ -15,18 +15,40 @@ foreign import Ntdll "system:Ntdll.lib"
@(default_calling_convention="stdcall")
foreign Ntdll {
RtlWaitOnAddress :: proc(Address: rawptr, CompareAddress: rawptr, AddressSize: uint, Timeout: ^i64) -> i32 ---
+ RtlNtStatusToDosError :: proc(status: i32) -> u32 ---
+ SetLastError :: proc(err: u32) ---
}
+
+/*
+ NOTE(bill, 2022-08-17)
+ WaitOnAddress is implemented on top of RtlWaitOnAddress
+ BUT requires taking the return value of it and if it is non-zero
+ converting that status to a DOS error and then SetLastError
+ If this is not done, then things don't work as expected when
+ and error occurs
+
+ GODDAMN MICROSOFT!
+*/
+CustomWaitOnAddress :: proc "stdcall" (Address: rawptr, CompareAddress: rawptr, AddressSize: uint, Timeout: ^i64) -> bool {
+ status := RtlWaitOnAddress(Address, CompareAddress, AddressSize, Timeout)
+ if status != 0 {
+ SetLastError(RtlNtStatusToDosError(status))
+ }
+ return status == 0
+}
+
+
_futex_wait :: proc(f: ^Futex, expect: u32) -> bool {
expect := expect
- return 0 == RtlWaitOnAddress(f, &expect, size_of(expect), nil)
+ return CustomWaitOnAddress(f, &expect, size_of(expect), nil)
}
_futex_wait_with_timeout :: proc(f: ^Futex, expect: u32, duration: time.Duration) -> bool {
expect := expect
// NOTE(bill): for some bizarre reason, this has be a negative number
timeout := -i64(duration / 100)
- return 0 == RtlWaitOnAddress(f, &expect, size_of(expect), &timeout)
+ return CustomWaitOnAddress(f, &expect, size_of(expect), &timeout)
}
_futex_signal :: proc(f: ^Futex) {