From a0862a29b43e6d5f0ecd2de07726099c1bdec8ce Mon Sep 17 00:00:00 2001 From: chzchzchz Date: Sun, 28 Mar 2021 17:55:31 -0700 Subject: [PATCH] JackLinuxFutex: treat maximum TimedWait() as Wait() and retry on EINTR FUTEX_WAIT may be interrupted by a signal and return EINTR. If a client process takes a signal while on the futex, the jack client may error out with no way to recover despite the signal being safe. Instead, retry if errno is set to EINTR. --- common/JackClient.cpp | 3 ++- linux/JackLinuxFutex.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/common/JackClient.cpp b/common/JackClient.cpp index b03dbc25..43de6b3e 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include +#include using namespace std; @@ -636,7 +637,7 @@ inline int JackClient::CallProcessCallback() inline bool JackClient::WaitSync() { // Suspend itself: wait on the input synchro - if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable, 0x7FFFFFFF) < 0) { + if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable, LONG_MAX) < 0) { jack_error("SuspendRefNum error"); return false; } else { diff --git a/linux/JackLinuxFutex.cpp b/linux/JackLinuxFutex.cpp index aef99cd2..1dcab737 100644 --- a/linux/JackLinuxFutex.cpp +++ b/linux/JackLinuxFutex.cpp @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackConstants.h" #include "JackError.h" #include "promiscuous.h" +#include #include #include #include @@ -98,13 +99,19 @@ bool JackLinuxFutex::Wait() if (__sync_bool_compare_and_swap(&fFutex->futex, 1, 0)) return true; - if (::syscall(SYS_futex, fFutex, fFutex->internal ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, 0, NULL, NULL, 0) != 0 && errno != EWOULDBLOCK) + if (::syscall(SYS_futex, fFutex, fFutex->internal ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, 0, NULL, NULL, 0) == 0) + continue; + + if (errno != EAGAIN && errno != EINTR) return false; } } bool JackLinuxFutex::TimedWait(long usec) { + if (usec == LONG_MAX) + return Wait(); + if (!fFutex) { jack_error("JackLinuxFutex::TimedWait name = %s already deallocated!!", fName); return false;