diff options
| author | gingerBill <bill@gingerbill.org> | 2022-08-17 13:12:45 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-08-17 13:12:45 +0100 |
| commit | 82765ca96e90f8ca3d2870e1b00bba3fecc0a78f (patch) | |
| tree | e21d92ed7b0e304b0c82126dd5562e51fea5b8e5 /core/sync | |
| parent | f2908cbc5aaec9c0472f1546f095eb4982a80232 (diff) | |
Fix `RtlWaitOnAddress` behaviour with `SetLastError(RtlNtStatusToDosError(status))` if an error occurred
Diffstat (limited to 'core/sync')
| -rw-r--r-- | core/sync/futex_windows.odin | 26 |
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) { |