Module: wine Branch: master Commit: ffccadd335066b49e57e7adbaa924868f0549904 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ffccadd335066b49e57e7adbaa...
Author: Alexandre Bique bique.alexandre@gmail.com Date: Thu Dec 12 18:54:48 2013 +0100
winealsa.drv: midiSeq must be protected by a critical section.
---
dlls/winealsa.drv/midi.c | 51 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c index 4e74440..6fc75ee 100644 --- a/dlls/winealsa.drv/midi.c +++ b/dlls/winealsa.drv/midi.c @@ -95,6 +95,14 @@ 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; @@ -222,6 +230,7 @@ static BOOL midi_warn = TRUE; */ static int midiOpenSeq(BOOL create_client) { + EnterCriticalSection(&midiSeqLock); if (numOpenMidiSeq == 0) { if (snd_seq_open(&midiSeq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { @@ -230,6 +239,7 @@ static int midiOpenSeq(BOOL create_client) WARN("Error opening ALSA sequencer.\n"); } midi_warn = FALSE; + LeaveCriticalSection(&midiSeqLock); return -1; }
@@ -262,6 +272,7 @@ static int midiOpenSeq(BOOL create_client) } } numOpenMidiSeq++; + LeaveCriticalSection(&midiSeqLock); return 0; }
@@ -270,12 +281,14 @@ static int midiOpenSeq(BOOL create_client) */ static int midiCloseSeq(void) { + EnterCriticalSection(&midiSeqLock); if (--numOpenMidiSeq == 0) { snd_seq_delete_simple_port(midiSeq, port_out); snd_seq_delete_simple_port(midiSeq, port_in); snd_seq_close(midiSeq); midiSeq = NULL; } + LeaveCriticalSection(&midiSeqLock); return 0; }
@@ -283,14 +296,17 @@ static DWORD WINAPI midRecThread(LPVOID arg) { int npfd; struct pollfd *pfd; + int ret;
TRACE("Thread startup\n");
while(!end_thread) { TRACE("Thread loop\n"); + EnterCriticalSection(&midiSeqLock); 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);
/* Check if an event is present */ if (poll(pfd, npfd, 250) <= 0) { @@ -309,7 +325,9 @@ static DWORD WINAPI midRecThread(LPVOID arg) do { WORD wDevID; snd_seq_event_t* ev; + EnterCriticalSection(&midiSeqLock); snd_seq_event_input(midiSeq, &ev); + LeaveCriticalSection(&midiSeqLock); /* Find the target device */ for (wDevID = 0; wDevID < MIDM_NumDevs; wDevID++) if ( (ev->source.client == MidiInDev[wDevID].addr.client) && (ev->source.port == MidiInDev[wDevID].addr.port) ) @@ -415,7 +433,11 @@ static DWORD WINAPI midRecThread(LPVOID arg) } } snd_seq_free_event(ev); - } while(snd_seq_event_input_pending(midiSeq, 0) > 0); + + EnterCriticalSection(&midiSeqLock); + ret = snd_seq_event_input_pending(midiSeq, 0); + LeaveCriticalSection(&midiSeqLock); + } while(ret > 0); HeapFree(GetProcessHeap(), 0, pfd); } @@ -443,6 +465,8 @@ static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPSW lpCaps, DWORD dwSize) */ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) { + int ret = 0; + TRACE("(%04X, %p, %08X);\n", wDevID, lpDesc, dwFlags);
if (lpDesc == NULL) { @@ -489,7 +513,11 @@ static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) MidiInDev[wDevID].startTime = 0;
/* Connect our app port to the device port */ - if (snd_seq_connect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port) < 0) + EnterCriticalSection(&midiSeqLock); + ret = snd_seq_connect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, + MidiInDev[wDevID].addr.port); + LeaveCriticalSection(&midiSeqLock); + if (ret < 0) return MMSYSERR_NOTENABLED;
TRACE("Input port :%d connected %d:%d\n",port_in,MidiInDev[wDevID].addr.client,MidiInDev[wDevID].addr.port); @@ -546,7 +574,9 @@ static DWORD midClose(WORD wDevID) TRACE("Stopped thread for midi-in\n"); }
+ EnterCriticalSection(&midiSeqLock); snd_seq_disconnect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port); + LeaveCriticalSection(&midiSeqLock); midiCloseSeq();
MidiInDev[wDevID].bufsize = 0; @@ -704,6 +734,8 @@ static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPSW lpCaps, DWORD dwSize) */ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) { + int ret; + TRACE("(%04X, %p, %08X);\n", wDevID, lpDesc, dwFlags); if (lpDesc == NULL) { WARN("Invalid Parameter !\n"); @@ -750,7 +782,11 @@ static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags) MidiOutDev[wDevID].midiDesc = *lpDesc;
/* Connect our app port to the device port */ - if (snd_seq_connect_to(midiSeq, port_out, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port) < 0) + EnterCriticalSection(&midiSeqLock); + ret = snd_seq_connect_to(midiSeq, port_out, MidiOutDev[wDevID].addr.client, + MidiOutDev[wDevID].addr.port); + LeaveCriticalSection(&midiSeqLock); + if (ret < 0) return MMSYSERR_NOTENABLED;
TRACE("Output port :%d connected %d:%d\n",port_out,MidiOutDev[wDevID].addr.client,MidiOutDev[wDevID].addr.port); @@ -785,7 +821,9 @@ static DWORD modClose(WORD wDevID) case MOD_FMSYNTH: case MOD_MIDIPORT: case MOD_SYNTH: + EnterCriticalSection(&midiSeqLock); snd_seq_disconnect_to(midiSeq, port_out, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port); + LeaveCriticalSection(&midiSeqLock); midiCloseSeq(); break; default: @@ -904,8 +942,11 @@ static DWORD modData(WORD wDevID, DWORD dwParam) } break; } - if (handled) + if (handled) { + EnterCriticalSection(&midiSeqLock); snd_seq_event_output_direct(midiSeq, &event); + LeaveCriticalSection(&midiSeqLock); + } } break; default: @@ -994,7 +1035,9 @@ static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize) snd_seq_ev_set_dest(&event, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port); TRACE("destination %d:%d\n", MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port); snd_seq_ev_set_sysex(&event, lpMidiHdr->dwBufferLength + len_add, lpNewData ? lpNewData : lpData); + EnterCriticalSection(&midiSeqLock); snd_seq_event_output_direct(midiSeq, &event); + LeaveCriticalSection(&midiSeqLock); HeapFree(GetProcessHeap(), 0, lpNewData); break; default: