Skip to content

Commit 322ba68

Browse files
committed
POSIX: Keep original timeout from sleep call
The `dispatch_sema4_timedwait` would reset the `_timeout` to an absolute time after the sleep was interrupted instead of when the sleep was called. Interrupting the process while it was sleeping would result in the new absolute timeout deadline being computed using the `timeout` offset from the time of the interrupt. e.g. if the timeout is 10 seconds, it will be ten seconds from when the process was interrupted because the absolute deadline was recomputed. Interrupting the process repeatedly while sleeping would will make the process go back to sleep instead of waking up when the original absolute deadline was reached. `timeout` is a relative timeout offset. `nsec` and `_timeout` are absolute times since the epoch specifying when the wait should stop.
1 parent 4029973 commit 322ba68

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

src/shims/lock.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,10 @@ _dispatch_sema4_timedwait(_dispatch_sema4_t *sema, dispatch_time_t timeout)
231231
struct timespec _timeout;
232232
int ret;
233233

234+
uint64_t nsec = _dispatch_time_nanoseconds_since_epoch(timeout);
235+
_timeout.tv_sec = (__typeof__(_timeout.tv_sec))(nsec / NSEC_PER_SEC);
236+
_timeout.tv_nsec = (__typeof__(_timeout.tv_nsec))(nsec % NSEC_PER_SEC);
234237
do {
235-
uint64_t nsec = _dispatch_time_nanoseconds_since_epoch(timeout);
236-
_timeout.tv_sec = (__typeof__(_timeout.tv_sec))(nsec / NSEC_PER_SEC);
237-
_timeout.tv_nsec = (__typeof__(_timeout.tv_nsec))(nsec % NSEC_PER_SEC);
238238
ret = sem_timedwait(sema, &_timeout);
239239
} while (unlikely(ret == -1 && errno == EINTR));
240240

0 commit comments

Comments
 (0)