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.
This commit is contained in:
chzchzchz 2021-03-28 17:55:31 -07:00 committed by Filipe Coelho
parent 8f4880518b
commit 01f0dabd14
2 changed files with 10 additions and 2 deletions

View File

@ -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 {

View File

@ -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;