From 79f9e1fe37ffe1ea26e9d1707c73f62159215f12 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Tue, 21 Feb 2012 13:09:05 +0100 Subject: [PATCH] Try more robust synchronization primitives in JackWinProcessSync. --- windows/JackWinProcessSync.cpp | 79 ++++++++++++++++++++++++++++------ windows/JackWinProcessSync.h | 8 ++-- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/windows/JackWinProcessSync.cpp b/windows/JackWinProcessSync.cpp index fa058b8e..02fe7b54 100644 --- a/windows/JackWinProcessSync.cpp +++ b/windows/JackWinProcessSync.cpp @@ -54,6 +54,7 @@ void JackWinProcessSync::LockedSignalAll() LockedSignal(); } +/* void JackWinProcessSync::Wait() { if (!ReleaseMutex(fMutex)) { @@ -64,6 +65,7 @@ void JackWinProcessSync::Wait() jack_error("JackWinProcessSync::Wait WaitForSingleObject err = %d", GetLastError()); } } +*/ void JackWinProcessSync::LockedWait() { @@ -71,26 +73,77 @@ void JackWinProcessSync::LockedWait() Wait(); } +/* bool JackWinProcessSync::TimedWait(long usec) { if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::TimedWait ReleaseMutex err = %d", GetLastError()); } - + DWORD res = WaitForSingleObject(fEvent, usec / 1000); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); } - + return (res == WAIT_OBJECT_0); } - +*/ bool JackWinProcessSync::LockedTimedWait(long usec) { // Does it make sense on Windows, use non-locked version for now... return TimedWait(usec); } +void JackWinProcessSync::Wait() +{ + // In case Wait is called in a "locked" context + if (ReleaseMutex(fMutex)) { + HANDLE handles[] = { fMutex, fEvent }; + DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); + if (res != WAIT_OBJECT_0) { + jack_error("JackWinProcessSync::Wait WaitForMultipleObjects err = %d", GetLastError()); + } + // In case Wait is called in a "non-locked" context + } else { + jack_error("JackWinProcessSync::Wait ReleaseMutex err = %d", GetLastError()); + DWORD res = WaitForSingleObject(fEvent, INFINITE); + if (res != WAIT_OBJECT_0) { + jack_error("JackWinProcessSync::Wait WaitForSingleObject err = %d", GetLastError()); + } + } + + if (!ResetEvent(fEvent)) { + jack_error("JackWinProcessSync::Wait ResetEvent err = %d", GetLastError()); + } +} + +bool JackWinProcessSync::TimedWait(long usec) +{ + DWORD res = 0; + + // In case TimedWait is called in a "locked" context + if (ReleaseMutex(fMutex)) { + HANDLE handles[] = { fMutex, fEvent }; + res = WaitForMultipleObjects(2, handles, true, usec / 1000); + if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) { + jack_error("JackWinProcessSync::TimedWait WaitForMultipleObjects err = %d", GetLastError()); + } + // In case TimedWait is called in a "non-locked" context + } else { + jack_error("JackWinProcessSync::TimedWait ReleaseMutex err = %d", GetLastError()); + res = WaitForSingleObject(fEvent, usec / 1000); + if (res != WAIT_OBJECT_0) { + jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); + } + } + + if (!ResetEvent(fEvent)) { + jack_error("JackWinProcessSync::TimedWait ResetEvent err = %d", GetLastError()); + } + + return (res == WAIT_OBJECT_0); +} + /* // Code from APPLE CAGuard.cpp : does not seem to work as expected... @@ -121,7 +174,7 @@ void JackWinProcessSync::Wait() jack_error("JackWinProcessSync::Wait WaitForSingleObject err = %d", GetLastError()); } } - + if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedWait ResetEvent err = %d", GetLastError()); } @@ -132,13 +185,13 @@ void JackWinProcessSync::LockedWait() if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::LockedWait ReleaseMutex err = %d", GetLastError()); } - + HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::LockedWait WaitForMultipleObjects err = %d", GetLastError()); } - + if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedWait ResetEvent err = %d", GetLastError()); } @@ -149,12 +202,12 @@ bool JackWinProcessSync::TimedWait(long usec) if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::TimedWait ReleaseMutex err = %d", GetLastError()); } - + DWORD res = WaitForSingleObject(fEvent, usec / 1000); if (res != WAIT_OBJECT_0) { jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); } - + return (res == WAIT_OBJECT_0); } @@ -174,11 +227,11 @@ bool JackWinProcessSync::TimedWait(long usec) jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); } } - + if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedTimedWait ResetEvent err = %d", GetLastError()); } - + return (res == WAIT_OBJECT_0); } @@ -187,17 +240,17 @@ bool JackWinProcessSync::LockedTimedWait(long usec) if (!ReleaseMutex(fMutex)) { jack_error("JackWinProcessSync::LockedTimedWait ReleaseMutex err = %d", GetLastError()); } - + HANDLE handles[] = { fMutex, fEvent }; DWORD res = WaitForMultipleObjects(2, handles, true, usec / 1000); if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) { jack_error("JackWinProcessSync::LockedTimedWait WaitForMultipleObjects err = %d", GetLastError()); } - + if (!ResetEvent(fEvent)) { jack_error("JackWinProcessSync::LockedTimedWait ResetEvent err = %d", GetLastError()); } - + return (res == WAIT_OBJECT_0); } */ diff --git a/windows/JackWinProcessSync.h b/windows/JackWinProcessSync.h index 57fb83ea..51842f46 100644 --- a/windows/JackWinProcessSync.h +++ b/windows/JackWinProcessSync.h @@ -43,11 +43,11 @@ class JackWinProcessSync : public JackWinMutex if (name) { char buffer[MAX_PATH]; snprintf(buffer, sizeof(buffer), "%s_%s", "JackWinProcessSync", name); - //fEvent = CreateEvent(NULL, TRUE, FALSE, buffer); // Needs ResetEvent - fEvent = CreateEvent(NULL, FALSE, FALSE, buffer); // Auto-reset event + fEvent = CreateEvent(NULL, TRUE, FALSE, buffer); // Needs ResetEvent + //fEvent = CreateEvent(NULL, FALSE, FALSE, buffer); // Auto-reset event } else { - //fEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // Needs ResetEvent - fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto-reset event + fEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // Needs ResetEvent + //fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto-reset event } ThrowIf((fEvent == 0), JackException("JackWinProcessSync: could not init the event"));