[PATCH 3/6] winealsa: Use a pipe to signal the end of the record thread.

Andrew Eikum aeikum at codeweavers.com
Fri Mar 25 08:59:24 CDT 2022


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Fri, Mar 25, 2022 at 08:42:16AM +0000, Huw Davies wrote:
> This means the thread doesn't have to wake every 250ms to test
> "end_thread".
> 
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
>  dlls/winealsa.drv/midi.c | 25 ++++++++++++++++++-------
>  1 file changed, 18 insertions(+), 7 deletions(-)
> 
> diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
> index 4cc906b03ca..327d4b7b200 100644
> --- a/dlls/winealsa.drv/midi.c
> +++ b/dlls/winealsa.drv/midi.c
> @@ -54,7 +54,7 @@ static	int 		MIDM_NumDevs = 0;
>  
>  static	int		numStartedMidiIn = 0;
>  
> -static int end_thread;
> +static int rec_cancel_pipe[2];
>  static HANDLE hThread;
>  
>  static void seq_lock(void)
> @@ -162,18 +162,25 @@ static DWORD WINAPI midRecThread(void *arg)
>      struct pollfd *pollfd;
>      int ret;
>  
> -    num_fds = snd_seq_poll_descriptors_count(midi_seq, POLLIN);
> +    /* Add on one for the read end of the cancel pipe */
> +    num_fds = snd_seq_poll_descriptors_count(midi_seq, POLLIN) + 1;
>      pollfd = malloc(num_fds * sizeof(struct pollfd));
>  
> -    while(!end_thread) {
> +    while(1) {
> +        pollfd[0].fd = rec_cancel_pipe[0];
> +        pollfd[0].events = POLLIN;
> +
>          seq_lock();
> -        snd_seq_poll_descriptors(midi_seq, pollfd, num_fds, POLLIN);
> +        snd_seq_poll_descriptors(midi_seq, pollfd + 1, num_fds - 1, POLLIN);
>          seq_unlock();
>  
>  	/* Check if an event is present */
> -        if (poll(pollfd, num_fds, 250) <= 0)
> +        if (poll(pollfd, num_fds, -1) <= 0)
>              continue;
>  
> +        if (pollfd[0].revents & POLLIN) /* cancelled */
> +            break;
> +
>  	do {
>              snd_seq_event_t *ev;
>  
> @@ -259,9 +266,11 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
>      TRACE("Input port :%d connected %d:%d\n",port_in,MidiInDev[wDevID].addr.client,MidiInDev[wDevID].addr.port);
>  
>      if (numStartedMidiIn++ == 0) {
> -	end_thread = 0;
> +	pipe(rec_cancel_pipe);
>  	hThread = CreateThread(NULL, 0, midRecThread, midi_seq, 0, NULL);
>  	if (!hThread) {
> +            close(rec_cancel_pipe[0]);
> +            close(rec_cancel_pipe[1]);
>  	    numStartedMidiIn = 0;
>  	    WARN("Couldn't create thread for midi-in\n");
>  	    midiCloseSeq();
> @@ -302,11 +311,13 @@ static DWORD midClose(WORD wDevID)
>      }
>      if (--numStartedMidiIn == 0) {
>  	TRACE("Stopping thread for midi-in\n");
> -	end_thread = 1;
> +        write(rec_cancel_pipe[1], "x", 1);
>  	if (WaitForSingleObject(hThread, 5000) != WAIT_OBJECT_0) {
>  	    WARN("Thread end not signaled, force termination\n");
>  	    TerminateThread(hThread, 0);
>  	}
> +        close(rec_cancel_pipe[0]);
> +        close(rec_cancel_pipe[1]);
>      	TRACE("Stopped thread for midi-in\n");
>      }
>  
> -- 
> 2.25.1
> 
> 



More information about the wine-devel mailing list