[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