Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52828 Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/winealsa.drv/alsamidi.c | 42 ++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c index 4f3f5538891..b226dac310f 100644 --- a/dlls/winealsa.drv/alsamidi.c +++ b/dlls/winealsa.drv/alsamidi.c @@ -90,7 +90,8 @@ static int rec_cancel_pipe[2]; static pthread_t rec_thread_id;
static pthread_mutex_t notify_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t notify_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t notify_read_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t notify_write_cond = PTHREAD_COND_INITIALIZER; static BOOL notify_quit; #define NOTIFY_BUFFER_SIZE 64 + 1 /* + 1 for the sentinel */ static struct notify_context notify_buffer[NOTIFY_BUFFER_SIZE]; @@ -156,19 +157,23 @@ static struct notify_context *notify_buffer_next(struct notify_context *notify) return notify; }
-static void notify_buffer_add(struct notify_context *notify) +static BOOL notify_buffer_empty(void) { - struct notify_context *next = notify_buffer_next(notify_write); + return notify_read == notify_write; +}
- if (next == notify_read) /* buffer is full - we can't issue a WARN() in a non-Win32 thread */ - notify_read = notify_buffer_next(notify_read); /* drop the oldest notification */ - *notify_write = *notify; - notify_write = next; +static BOOL notify_buffer_full(void) +{ + return notify_buffer_next(notify_write) == notify_read; }
-static BOOL notify_buffer_empty(void) +static BOOL notify_buffer_add(struct notify_context *notify) { - return notify_read == notify_write; + if (notify_buffer_full()) return FALSE; + + *notify_write = *notify; + notify_write = notify_buffer_next(notify_write); + return TRUE; }
static BOOL notify_buffer_remove(struct notify_context *notify) @@ -184,9 +189,15 @@ static void notify_post(struct notify_context *notify) { pthread_mutex_lock(¬ify_mutex);
- if (notify) notify_buffer_add(notify); + if (notify) + { + while (notify_buffer_full()) + pthread_cond_wait(¬ify_write_cond, ¬ify_mutex); + + notify_buffer_add(notify); + } else notify_quit = TRUE; - pthread_cond_signal(¬ify_cond); + pthread_cond_signal(¬ify_read_cond);
pthread_mutex_unlock(¬ify_mutex); } @@ -1476,11 +1487,14 @@ NTSTATUS midi_notify_wait(void *args) pthread_mutex_lock(¬ify_mutex);
while (!notify_quit && notify_buffer_empty()) - pthread_cond_wait(¬ify_cond, ¬ify_mutex); + pthread_cond_wait(¬ify_read_cond, ¬ify_mutex);
*params->quit = notify_quit; - if (!notify_quit) notify_buffer_remove(params->notify); - + if (!notify_quit) + { + notify_buffer_remove(params->notify); + pthread_cond_signal(¬ify_write_cond); + } pthread_mutex_unlock(¬ify_mutex);
return STATUS_SUCCESS;
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Tue, Apr 19, 2022 at 01:18:33PM +0100, Huw Davies wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52828 Signed-off-by: Huw Davies huw@codeweavers.com
dlls/winealsa.drv/alsamidi.c | 42 ++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c index 4f3f5538891..b226dac310f 100644 --- a/dlls/winealsa.drv/alsamidi.c +++ b/dlls/winealsa.drv/alsamidi.c @@ -90,7 +90,8 @@ static int rec_cancel_pipe[2]; static pthread_t rec_thread_id;
static pthread_mutex_t notify_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t notify_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t notify_read_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t notify_write_cond = PTHREAD_COND_INITIALIZER; static BOOL notify_quit; #define NOTIFY_BUFFER_SIZE 64 + 1 /* + 1 for the sentinel */ static struct notify_context notify_buffer[NOTIFY_BUFFER_SIZE]; @@ -156,19 +157,23 @@ static struct notify_context *notify_buffer_next(struct notify_context *notify) return notify; }
-static void notify_buffer_add(struct notify_context *notify) +static BOOL notify_buffer_empty(void) {
- struct notify_context *next = notify_buffer_next(notify_write);
- return notify_read == notify_write;
+}
- if (next == notify_read) /* buffer is full - we can't issue a WARN() in a non-Win32 thread */
notify_read = notify_buffer_next(notify_read); /* drop the oldest notification */
- *notify_write = *notify;
- notify_write = next;
+static BOOL notify_buffer_full(void) +{
- return notify_buffer_next(notify_write) == notify_read;
}
-static BOOL notify_buffer_empty(void) +static BOOL notify_buffer_add(struct notify_context *notify) {
- return notify_read == notify_write;
- if (notify_buffer_full()) return FALSE;
- *notify_write = *notify;
- notify_write = notify_buffer_next(notify_write);
- return TRUE;
}
static BOOL notify_buffer_remove(struct notify_context *notify) @@ -184,9 +189,15 @@ static void notify_post(struct notify_context *notify) { pthread_mutex_lock(¬ify_mutex);
- if (notify) notify_buffer_add(notify);
- if (notify)
- {
while (notify_buffer_full())
pthread_cond_wait(¬ify_write_cond, ¬ify_mutex);
notify_buffer_add(notify);
- } else notify_quit = TRUE;
- pthread_cond_signal(¬ify_cond);
pthread_cond_signal(¬ify_read_cond);
pthread_mutex_unlock(¬ify_mutex);
} @@ -1476,11 +1487,14 @@ NTSTATUS midi_notify_wait(void *args) pthread_mutex_lock(¬ify_mutex);
while (!notify_quit && notify_buffer_empty())
pthread_cond_wait(¬ify_cond, ¬ify_mutex);
pthread_cond_wait(¬ify_read_cond, ¬ify_mutex);
*params->quit = notify_quit;
- if (!notify_quit) notify_buffer_remove(params->notify);
if (!notify_quit)
{
notify_buffer_remove(params->notify);
pthread_cond_signal(¬ify_write_cond);
} pthread_mutex_unlock(¬ify_mutex);
return STATUS_SUCCESS;
-- 2.25.1