Alexandre Bique : winealsa.drv: midiSeq must be protected by a critical section.

Alexandre Julliard julliard at winehq.org
Mon Dec 16 13:02:32 CST 2013


Module: wine
Branch: master
Commit: ffccadd335066b49e57e7adbaa924868f0549904
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ffccadd335066b49e57e7adbaa924868f0549904

Author: Alexandre Bique <bique.alexandre at 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:




More information about the wine-cvs mailing list