[PATCH 4/4] winealsa: Move the midi seq lock to the unixlib.

Andrew Eikum aeikum at codeweavers.com
Mon Mar 14 08:45:28 CDT 2022


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

On Mon, Mar 14, 2022 at 10:21:49AM +0000, Huw Davies wrote:
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
>  dlls/winealsa.drv/Makefile.in |  1 +
>  dlls/winealsa.drv/alsa.c      |  2 +
>  dlls/winealsa.drv/alsamidi.c  | 64 +++++++++++++++++++++++
>  dlls/winealsa.drv/midi.c      | 97 +++++++++++++++++------------------
>  dlls/winealsa.drv/unixlib.h   |  4 ++
>  5 files changed, 118 insertions(+), 50 deletions(-)
>  create mode 100644 dlls/winealsa.drv/alsamidi.c
> 
> diff --git a/dlls/winealsa.drv/Makefile.in b/dlls/winealsa.drv/Makefile.in
> index 2158e087251..41be57d8b83 100644
> --- a/dlls/winealsa.drv/Makefile.in
> +++ b/dlls/winealsa.drv/Makefile.in
> @@ -9,5 +9,6 @@ EXTRADLLFLAGS = -mcygwin
>  
>  C_SRCS = \
>  	alsa.c \
> +	alsamidi.c \
>  	midi.c \
>  	mmdevdrv.c
> diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
> index 085066622c0..cdc3d81d8cc 100644
> --- a/dlls/winealsa.drv/alsa.c
> +++ b/dlls/winealsa.drv/alsa.c
> @@ -2444,4 +2444,6 @@ unixlib_entry_t __wine_unix_call_funcs[] =
>      set_event_handle,
>      is_started,
>      get_prop_value,
> +
> +    midi_seq_lock, /* temporary */
>  };
> diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c
> new file mode 100644
> index 00000000000..ab4de4f7f9e
> --- /dev/null
> +++ b/dlls/winealsa.drv/alsamidi.c
> @@ -0,0 +1,64 @@
> +/*
> + * MIDI driver for ALSA (unixlib)
> + *
> + * Copyright 1994       Martin Ayotte
> + * Copyright 1998       Luiz Otavio L. Zorzella
> + * Copyright 1998, 1999 Eric POUECH
> + * Copyright 2003       Christian Costa
> + * Copyright 2022       Huw Davies
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
> + */
> +
> +#if 0
> +#pragma makedep unix
> +#endif
> +
> +#include "config.h"
> +
> +#include <stdarg.h>
> +#include <stdio.h>
> +#include <pthread.h>
> +
> +#include "ntstatus.h"
> +#define WIN32_NO_STATUS
> +#include "windef.h"
> +#include "winbase.h"
> +#include "winternl.h"
> +#include "mmdeviceapi.h"
> +
> +#include "wine/unixlib.h"
> +
> +#include "unixlib.h"
> +
> +static pthread_mutex_t seq_mutex = PTHREAD_MUTEX_INITIALIZER;
> +
> +static void seq_lock(void)
> +{
> +    pthread_mutex_lock(&seq_mutex);
> +}
> +
> +static void seq_unlock(void)
> +{
> +    pthread_mutex_unlock(&seq_mutex);
> +}
> +
> +NTSTATUS midi_seq_lock(void *args)
> +{
> +    if (args) seq_lock();
> +    else seq_unlock();
> +
> +    return STATUS_SUCCESS;
> +}
> diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
> index e65cae6cda5..dff77ce88d8 100644
> --- a/dlls/winealsa.drv/midi.c
> +++ b/dlls/winealsa.drv/midi.c
> @@ -1,17 +1,11 @@
> -/* -*- tab-width: 8; c-basic-offset: 4 -*- */
> -
>  /*
> - * Sample MIDI Wine Driver for ALSA (basically Linux)
> + * MIDI driver for ALSA (PE-side)
>   *
> - * Copyright 1994 	Martin Ayotte
> - * Copyright 1998 	Luiz Otavio L. Zorzella (init procedures)
> - * Copyright 1998/1999	Eric POUECH :
> - * 		98/7 	changes for making this MIDI driver work on OSS
> - * 			current support is limited to MIDI ports of OSS systems
> - * 		98/9	rewriting MCI code for MIDI
> - * 		98/11 	split in midi.c and mcimidi.c
> - * Copyright 2003      Christian Costa :
> - *                     ALSA port
> + * Copyright 1994       Martin Ayotte
> + * Copyright 1998       Luiz Otavio L. Zorzella
> + * Copyright 1998, 1999 Eric POUECH
> + * Copyright 2003       Christian Costa
> + * Copyright 2022       Huw Davies
>   *
>   * This library is free software; you can redistribute it and/or
>   * modify it under the terms of the GNU Lesser General Public
> @@ -26,9 +20,6 @@
>   * You should have received a copy of the GNU Lesser General Public
>   * License along with this library; if not, write to the Free Software
>   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
> - *
> - * TODO: Finish midi record
> - *
>   */
>  
>  #include "config.h"
> @@ -40,18 +31,22 @@
>  #include <fcntl.h>
>  #include <errno.h>
>  
> +#include "ntstatus.h"
> +#define WIN32_NO_STATUS
>  #include "windef.h"
>  #include "winbase.h"
>  #include "wingdi.h"
> -#include "winuser.h"
> -#include "winnls.h"
> +#include "winternl.h"
>  #include "mmddk.h"
> -#include "mmreg.h"
> -#include "dsound.h"
> +#include "mmdeviceapi.h"
> +
>  #include "wine/debug.h"
> +#include "wine/unixlib.h"
>  
>  #include <alsa/asoundlib.h>
>  
> +#include "unixlib.h"
> +
>  WINE_DEFAULT_DEBUG_CHANNEL(midi);
>  
>  typedef struct {
> @@ -81,14 +76,6 @@ static	int 		MODM_NumDevs = 0;
>  /* this is the total number of MIDI out devices found */
>  static	int 		MIDM_NumDevs = 0;
>  
> -static CRITICAL_SECTION midiSeqLock;
> -static CRITICAL_SECTION_DEBUG midiSeqLockDebug =
> -{
> -    0, 0, &midiSeqLock,
> -    { &midiSeqLockDebug.ProcessLocksList, &midiSeqLockDebug.ProcessLocksList },
> -      0, 0, { (DWORD_PTR)(__FILE__ ": midiSeqLock") }
> -};
> -static CRITICAL_SECTION midiSeqLock = { &midiSeqLockDebug, -1, 0, 0, 0, 0 };
>  static	snd_seq_t*      midiSeq = NULL;
>  static	int		numOpenMidiSeq = 0;
>  static	int		numStartedMidiIn = 0;
> @@ -107,6 +94,16 @@ static CRITICAL_SECTION crit_sect = { &critsect_debug, -1, 0, 0, 0, 0 };
>  static int end_thread;
>  static HANDLE hThread;
>  
> +static void seq_lock(void)
> +{
> +    ALSA_CALL(midi_seq_lock, (void *)(UINT_PTR)1);
> +}
> +
> +static void seq_unlock(void)
> +{
> +    ALSA_CALL(midi_seq_lock, (void *)(UINT_PTR)0);
> +}
> +
>  /*======================================================================*
>   *                  Low level MIDI implementation			*
>   *======================================================================*/
> @@ -215,7 +212,7 @@ static BOOL midi_warn = TRUE;
>   */
>  static int midiOpenSeq(BOOL create_client)
>  {
> -    EnterCriticalSection(&midiSeqLock);
> +    seq_lock();
>      if (numOpenMidiSeq == 0) {
>  	if (snd_seq_open(&midiSeq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0)
>          {
> @@ -224,7 +221,7 @@ static int midiOpenSeq(BOOL create_client)
>  		WARN("Error opening ALSA sequencer.\n");
>  	    }
>              midi_warn = FALSE;
> -            LeaveCriticalSection(&midiSeqLock);
> +            seq_unlock();
>  	    return -1;
>  	}
>  
> @@ -242,7 +239,7 @@ static int midiOpenSeq(BOOL create_client)
>          }
>      }
>      numOpenMidiSeq++;
> -    LeaveCriticalSection(&midiSeqLock);
> +    seq_unlock();
>      return 0;
>  }
>  
> @@ -251,13 +248,13 @@ static int midiOpenSeq(BOOL create_client)
>   */
>  static int midiCloseSeq(void)
>  {
> -    EnterCriticalSection(&midiSeqLock);
> +    seq_lock();
>      if (--numOpenMidiSeq == 0) {
>  	snd_seq_delete_simple_port(midiSeq, port_in);
>  	snd_seq_close(midiSeq);
>  	midiSeq = NULL;
>      }
> -    LeaveCriticalSection(&midiSeqLock);
> +    seq_unlock();
>      return 0;
>  }
>  
> @@ -381,11 +378,11 @@ static DWORD WINAPI midRecThread(LPVOID arg)
>  
>      while(!end_thread) {
>  	TRACE("Thread loop\n");
> -        EnterCriticalSection(&midiSeqLock);
> +        seq_lock();
>  	npfd = snd_seq_poll_descriptors_count(midiSeq, POLLIN);
>  	pfd = HeapAlloc(GetProcessHeap(), 0, npfd * sizeof(struct pollfd));
>  	snd_seq_poll_descriptors(midiSeq, pfd, npfd, POLLIN);
> -        LeaveCriticalSection(&midiSeqLock);
> +        seq_unlock();
>  
>  	/* Check if an event is present */
>  	if (poll(pfd, npfd, 250) <= 0) {
> @@ -404,18 +401,18 @@ static DWORD WINAPI midRecThread(LPVOID arg)
>  	do {
>              snd_seq_event_t *ev;
>  
> -            EnterCriticalSection(&midiSeqLock);
> +            seq_lock();
>              snd_seq_event_input(midiSeq, &ev);
> -            LeaveCriticalSection(&midiSeqLock);
> +            seq_unlock();
>  
>              if (ev) {
>                  handle_midi_event(ev);
>                  snd_seq_free_event(ev);
>              }
>  
> -            EnterCriticalSection(&midiSeqLock);
> +            seq_lock();
>              ret = snd_seq_event_input_pending(midiSeq, 0);
> -            LeaveCriticalSection(&midiSeqLock);
> +            seq_unlock();
>  	} while(ret > 0);
>  	
>  	HeapFree(GetProcessHeap(), 0, pfd);
> @@ -489,10 +486,10 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
>      MidiInDev[wDevID].startTime = 0;
>  
>      /* Connect our app port to the device port */
> -    EnterCriticalSection(&midiSeqLock);
> +    seq_lock();
>      ret = snd_seq_connect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client,
>                                 MidiInDev[wDevID].addr.port);
> -    LeaveCriticalSection(&midiSeqLock);
> +    seq_unlock();
>      if (ret < 0)
>  	return MMSYSERR_NOTENABLED;
>  
> @@ -550,9 +547,9 @@ static DWORD midClose(WORD wDevID)
>      	TRACE("Stopped thread for midi-in\n");
>      }
>  
> -    EnterCriticalSection(&midiSeqLock);
> +    seq_lock();
>      snd_seq_disconnect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port);
> -    LeaveCriticalSection(&midiSeqLock);
> +    seq_unlock();
>      midiCloseSeq();
>  
>      MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L);
> @@ -752,7 +749,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
>      MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
>      MidiOutDev[wDevID].midiDesc = *lpDesc;
>  
> -    EnterCriticalSection(&midiSeqLock);
> +    seq_lock();
>      /* Create a port dedicated to a specific device */
>      /* Keep the old name without a number for the first port */
>      if (wDevID)
> @@ -780,7 +777,7 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
>  		 wDevID, MidiOutDev[wDevID].addr.client,
>  		 MidiOutDev[wDevID].addr.port, snd_strerror(ret));
>      }
> -    LeaveCriticalSection(&midiSeqLock);
> +    seq_unlock();
>  
>      if (port_out < 0)
>  	return MMSYSERR_NOTENABLED;
> @@ -817,11 +814,11 @@ static DWORD modClose(WORD wDevID)
>      case MOD_FMSYNTH:
>      case MOD_MIDIPORT:
>      case MOD_SYNTH:
> -        EnterCriticalSection(&midiSeqLock);
> +        seq_lock();
>          TRACE("Deleting port :%d, connected to %d:%d\n", MidiOutDev[wDevID].port_out, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port);
>          snd_seq_delete_simple_port(midiSeq, MidiOutDev[wDevID].port_out);
>          MidiOutDev[wDevID].port_out = -1;
> -        LeaveCriticalSection(&midiSeqLock);
> +        seq_unlock();
>  	midiCloseSeq();
>  	break;
>      default:
> @@ -942,9 +939,9 @@ static DWORD modData(WORD wDevID, DWORD dwParam)
>  		break;
>  	    }
>  	    if (handled) {
> -                EnterCriticalSection(&midiSeqLock);
> +                seq_lock();
>                  snd_seq_event_output_direct(midiSeq, &event);
> -                LeaveCriticalSection(&midiSeqLock);
> +                seq_unlock();
>              }
>  	}
>  	break;
> @@ -1033,9 +1030,9 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
>  	snd_seq_ev_set_source(&event, MidiOutDev[wDevID].port_out);
>  	snd_seq_ev_set_subs(&event);
>  	snd_seq_ev_set_sysex(&event, lpMidiHdr->dwBufferLength + len_add, lpNewData ? lpNewData : lpData);
> -        EnterCriticalSection(&midiSeqLock);
> +        seq_lock();
>  	snd_seq_event_output_direct(midiSeq, &event);
> -        LeaveCriticalSection(&midiSeqLock);
> +        seq_unlock();
>          HeapFree(GetProcessHeap(), 0, lpNewData);
>          break;
>      default:
> diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
> index c2de48cef65..89afcb71bec 100644
> --- a/dlls/winealsa.drv/unixlib.h
> +++ b/dlls/winealsa.drv/unixlib.h
> @@ -232,8 +232,12 @@ enum alsa_funcs
>      alsa_set_event_handle,
>      alsa_is_started,
>      alsa_get_prop_value,
> +
> +    alsa_midi_seq_lock, /* temporary */
>  };
>  
> +NTSTATUS midi_seq_lock(void *args) DECLSPEC_HIDDEN;
> +
>  extern unixlib_handle_t alsa_handle;
>  
>  #define ALSA_CALL(func, params) __wine_unix_call(alsa_handle, alsa_ ## func, params)
> -- 
> 2.25.1
> 
> 



More information about the wine-devel mailing list