| ... | @@ -2021,9 +2021,7 @@ pub const Event = enum(u32) { | ... | @@ -2021,9 +2021,7 @@ pub const Event = enum(u32) { |
| 2021 | | 2021 | |
| 2022 | pub const WaitTimeoutError = error{Timeout} || Cancelable; | 2022 | pub const WaitTimeoutError = error{Timeout} || Cancelable; |
| 2023 | | 2023 | |
| 2024 | /// Blocks the calling thread until either the logical boolean is set, the timeout expires, or a | 2024 | /// Blocks the calling thread until either the logical boolean is set or the timeout expires. |
| 2025 | /// spurious wakeup occurs. If the timeout expires or a spurious wakeup occurs, `error.Timeout` | | |
| 2026 | /// is returned. | | |
| 2027 | pub fn waitTimeout(event: *Event, io: Io, timeout: Timeout) WaitTimeoutError!void { | 2025 | pub fn waitTimeout(event: *Event, io: Io, timeout: Timeout) WaitTimeoutError!void { |
| 2028 | if (@cmpxchgStrong(Event, event, .unset, .waiting, .acquire, .acquire)) |prev| switch (prev) { | 2026 | if (@cmpxchgStrong(Event, event, .unset, .waiting, .acquire, .acquire)) |prev| switch (prev) { |
| 2029 | .unset => unreachable, | 2027 | .unset => unreachable, |
| ... | @@ -2037,11 +2035,19 @@ pub const Event = enum(u32) { | ... | @@ -2037,11 +2035,19 @@ pub const Event = enum(u32) { |
| 2037 | // waiters would wake up when a *new waiter* was added. So it's easiest to just leave | 2035 | // waiters would wake up when a *new waiter* was added. So it's easiest to just leave |
| 2038 | // the state at `.waiting`---at worst it causes one redundant call to `futexWake`. | 2036 | // the state at `.waiting`---at worst it causes one redundant call to `futexWake`. |
| 2039 | } | 2037 | } |
| 2040 | try io.futexWaitTimeout(Event, event, .waiting, timeout); | 2038 | |
| 2041 | switch (@atomicLoad(Event, event, .acquire)) { | 2039 | const deadline = timeout.toDeadline(io); |
| 2042 | .unset => unreachable, // `reset` called before pending `wait` returned | 2040 | |
| 2043 | .waiting => return error.Timeout, | 2041 | while (true) { |
| 2044 | .is_set => return, | 2042 | try io.futexWaitTimeout(Event, event, .waiting, timeout); |
| | 2043 | switch (@atomicLoad(Event, event, .acquire)) { |
| | 2044 | .unset => unreachable, // `reset` called before pending `wait` returned |
| | 2045 | .waiting => { |
| | 2046 | const remaining = deadline.toDurationFromNow(io) orelse continue; |
| | 2047 | if (remaining.raw.nanoseconds <= 0) return error.Timeout; |
| | 2048 | }, |
| | 2049 | .is_set => return, |
| | 2050 | } |
| 2045 | } | 2051 | } |
| 2046 | } | 2052 | } |
| 2047 | | 2053 | |