diff options
author | chzchzchz <chzchzchz@users.noreply.github.com> | 2021-03-28 17:55:31 -0700 |
---|---|---|
committer | Filipe Coelho <falktx@falktx.com> | 2021-04-14 16:20:02 +0100 |
commit | 01f0dabd14bc07a75ea153219a56d1eb60df256e (patch) | |
tree | f8b716e71d39effe8e9c842498105e3afee6078e | |
parent | 8f4880518b2d1aeed7381feb84ccffea8800b4f4 (diff) | |
download | jack2-01f0dabd14bc07a75ea153219a56d1eb60df256e.tar.gz |
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.
-rw-r--r-- | common/JackClient.cpp | 3 | ||||
-rw-r--r-- | 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 <math.h> #include <string> #include <algorithm> +#include <climits> 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 <climits> #include <fcntl.h> #include <stdio.h> #include <sys/mman.h> @@ -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; |