summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchzchzchz <chzchzchz@users.noreply.github.com>2021-03-28 17:55:31 -0700
committerFilipe Coelho <falktx@falktx.com>2021-04-14 16:20:02 +0100
commit01f0dabd14bc07a75ea153219a56d1eb60df256e (patch)
treef8b716e71d39effe8e9c842498105e3afee6078e
parent8f4880518b2d1aeed7381feb84ccffea8800b4f4 (diff)
downloadjack2-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.cpp3
-rw-r--r--linux/JackLinuxFutex.cpp9
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;