| ... | @@ -2052,9 +2052,7 @@ pub const Event = enum(u32) { | ... | @@ -2052,9 +2052,7 @@ pub const Event = enum(u32) { |
| 2052 | | 2052 | |
| 2053 | pub const WaitTimeoutError = error{Timeout} || Cancelable; | 2053 | pub const WaitTimeoutError = error{Timeout} || Cancelable; |
| 2054 | | 2054 | |
| 2055 | /// Blocks the calling thread until either the logical boolean is set, the timeout expires, or a | 2055 | /// Blocks the calling thread until either the logical boolean is set or the timeout expires. |
| 2056 | /// spurious wakeup occurs. If the timeout expires or a spurious wakeup occurs, `error.Timeout` | | |
| 2057 | /// is returned. | | |
| 2058 | pub fn waitTimeout(event: *Event, io: Io, timeout: Timeout) WaitTimeoutError!void { | 2056 | pub fn waitTimeout(event: *Event, io: Io, timeout: Timeout) WaitTimeoutError!void { |
| 2059 | if (@cmpxchgStrong(Event, event, .unset, .waiting, .acquire, .acquire)) |prev| switch (prev) { | 2057 | if (@cmpxchgStrong(Event, event, .unset, .waiting, .acquire, .acquire)) |prev| switch (prev) { |
| 2060 | .unset => unreachable, | 2058 | .unset => unreachable, |
| ... | @@ -2068,11 +2066,19 @@ pub const Event = enum(u32) { | ... | @@ -2068,11 +2066,19 @@ pub const Event = enum(u32) { |
| 2068 | // waiters would wake up when a *new waiter* was added. So it's easiest to just leave | 2066 | // waiters would wake up when a *new waiter* was added. So it's easiest to just leave |
| 2069 | // the state at `.waiting`---at worst it causes one redundant call to `futexWake`. | 2067 | // the state at `.waiting`---at worst it causes one redundant call to `futexWake`. |
| 2070 | } | 2068 | } |
| 2071 | try io.futexWaitTimeout(Event, event, .waiting, timeout); | 2069 | |
| 2072 | switch (@atomicLoad(Event, event, .acquire)) { | 2070 | const deadline = timeout.toDeadline(io); |
| 2073 | .unset => unreachable, // `reset` called before pending `wait` returned | 2071 | |
| 2074 | .waiting => return error.Timeout, | 2072 | while (true) { |
| 2075 | .is_set => return, | 2073 | try io.futexWaitTimeout(Event, event, .waiting, timeout); |
| | 2074 | switch (@atomicLoad(Event, event, .acquire)) { |
| | 2075 | .unset => unreachable, // `reset` called before pending `wait` returned |
| | 2076 | .waiting => { |
| | 2077 | const remaining = deadline.toDurationFromNow(io) orelse continue; |
| | 2078 | if (remaining.raw.nanoseconds <= 0) return error.Timeout; |
| | 2079 | }, |
| | 2080 | .is_set => return, |
| | 2081 | } |
| 2076 | } | 2082 | } |
| 2077 | } | 2083 | } |
| 2078 | | 2084 | |