Skip to content

Commit

Permalink
Merge pull request #1068 from Mathewnd/master
Browse files Browse the repository at this point in the history
options/posix: fix sys_futex_wait handling and fix an issue in pthread_once
  • Loading branch information
Geertiebear authored Jun 4, 2024
2 parents 7dac3ca + 5583d27 commit 1580691
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 3 deletions.
3 changes: 2 additions & 1 deletion options/internal/generic/threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ int thread_mutex_lock(struct __mlibc_mutex *mutex) {

// If the wait returns EAGAIN, that means that the mutex_waiters_bit was just unset by
// some other thread. In this case, we should loop back around.
if (e && e != EAGAIN)
// Also do so in case of a signal being caught.
if (e && e != EAGAIN && e != EINTR)
mlibc::panicLogger() << "sys_futex_wait() failed with error code " << e << frg::endlog;

// Opportunistically try to take the lock after we wake up.
Expand Down
3 changes: 2 additions & 1 deletion options/internal/include/mlibc/lock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ struct FutexLockImpl {

// If the wait returns EAGAIN, that means that the waitersBit was just unset by
// some other thread. In this case, we should loop back around.
if (e && e != EAGAIN)
// Also loop around in case of a signal interrupting the wait
if (e && e != EAGAIN && e != EINTR)
mlibc::panicLogger() << "sys_futex_wait() failed with error code " << e << frg::endlog;

// Opportunistically try to take the lock after we wake up.
Expand Down
5 changes: 4 additions & 1 deletion options/posix/generic/pthread-stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,10 @@ int pthread_once(pthread_once_t *once, void (*function) (void)) {
}else{
// a different thread is currently running the initializer.
__ensure(expected == onceLocked);
if(int e = mlibc::sys_futex_wait((int *)&once->__mlibc_done, onceLocked, nullptr); e)
// if the wait gets interrupted by a signal, check again.
// EAGAIN will also be a retry, as it means the other thread completed
// and changed the __mlibc_done variable to signal it before we actually went to sleep.
if(int e = mlibc::sys_futex_wait((int *)&once->__mlibc_done, onceLocked, nullptr); e && e != EINTR && e != EAGAIN)
__ensure(!"sys_futex_wait() failed");
expected = __atomic_load_n(&once->__mlibc_done, __ATOMIC_ACQUIRE);
}
Expand Down

0 comments on commit 1580691

Please sign in to comment.