[PATCH] winealsa: Wait for the notify buffer to empty, rather than dropping an event.
Huw Davies
huw at codeweavers.com
Tue Apr 19 07:18:33 CDT 2022
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52828
Signed-off-by: Huw Davies <huw at 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
More information about the wine-devel
mailing list