From: kettenis Date: Sun, 13 Jun 2021 21:11:54 +0000 (+0000) Subject: Save and restore errno around FUTEX_WAIT futex(2) operations. While there X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=96f2311e04d3f1f278964710d74f358d01e32a15;p=openbsd Save and restore errno around FUTEX_WAIT futex(2) operations. While there remove the unused _wait() function in librthread such that we don't have to add the save/restore sequence there. Fixed building Python as a race with another thread unlocking a futex(2) would make futex(2) set errno to EAGAIN which would confuse Python in beleiving that readdir(2) failed instead of reaching the end of the directory. Spotted and tested by tb@ ok bluhm@ --- diff --git a/lib/libc/thread/synch.h b/lib/libc/thread/synch.h index 91b5001c515..6b9fab1642d 100644 --- a/lib/libc/thread/synch.h +++ b/lib/libc/thread/synch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: synch.h,v 1.6 2021/05/21 16:52:42 kettenis Exp $ */ +/* $OpenBSD: synch.h,v 1.7 2021/06/13 21:11:54 kettenis Exp $ */ /* * Copyright (c) 2017 Martin Pieuchot * @@ -29,12 +29,15 @@ static inline int _twait(volatile uint32_t *p, int val, clockid_t clockid, const struct timespec *abs) { struct timespec rel; + int saved_errno = errno; int error; if (abs == NULL) { error = futex(p, FUTEX_WAIT_PRIVATE, val, NULL, NULL); - if (error == -1) + if (error == -1) { error = errno; + errno = saved_errno; + } return error; } @@ -50,8 +53,10 @@ _twait(volatile uint32_t *p, int val, clockid_t clockid, const struct timespec * return ETIMEDOUT; error = futex(p, FUTEX_WAIT_PRIVATE, val, &rel, NULL); - if (error == -1) + if (error == -1) { error = errno; + errno = saved_errno; + } return error; } diff --git a/lib/librthread/synch.h b/lib/librthread/synch.h index e5c623e87a0..e6ad156778c 100644 --- a/lib/librthread/synch.h +++ b/lib/librthread/synch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: synch.h,v 1.7 2021/05/21 16:52:42 kettenis Exp $ */ +/* $OpenBSD: synch.h,v 1.8 2021/06/13 21:11:54 kettenis Exp $ */ /* * Copyright (c) 2017 Martin Pieuchot * @@ -25,23 +25,19 @@ _wake(volatile uint32_t *p, int n) return futex(p, FUTEX_WAKE, n, NULL, NULL); } -static inline void -_wait(volatile uint32_t *p, int val) -{ - while (*p != (uint32_t)val) - futex(p, FUTEX_WAIT, val, NULL, NULL); -} - static inline int _twait(volatile uint32_t *p, int val, clockid_t clockid, const struct timespec *abs) { struct timespec rel; + int saved_errno = errno; int error; if (abs == NULL) { error = futex(p, FUTEX_WAIT, val, NULL, NULL); - if (error == -1) + if (error == -1) { error = errno; + errno = saved_errno; + } return error; } @@ -57,8 +53,10 @@ _twait(volatile uint32_t *p, int val, clockid_t clockid, const struct timespec * return ETIMEDOUT; error = futex(p, FUTEX_WAIT, val, &rel, NULL); - if (error == -1) + if (error == -1) { error = errno; + errno = saved_errno; + } return error; }