[PATCH] winealsa: Wait for the notify buffer to empty, rather than dropping an event.
Andrew Eikum
aeikum at codeweavers.com
Tue Apr 19 09:31:06 CDT 2022
Signed-off-by: Andrew Eikum <aeikum at 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 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