[PATCH 2/3] mciwave: try to synchronize better async commands

Eric Pouech eric.pouech at orange.fr
Sat Oct 17 03:08:43 CDT 2009


ie, wait for command handling to do it's initialization before returning from the command

A+
---

 dlls/mciwave/mciwave.c |   34 ++++++++++++++++++++++++----------
 1 files changed, 24 insertions(+), 10 deletions(-)


diff --git a/dlls/mciwave/mciwave.c b/dlls/mciwave/mciwave.c
index 5571b1f..8729bfb 100644
--- a/dlls/mciwave/mciwave.c
+++ b/dlls/mciwave/mciwave.c
@@ -62,10 +62,11 @@ typedef struct {
  * ===================================================================
  * =================================================================== */
 
-typedef DWORD (*async_cmd)(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt);
+typedef DWORD (*async_cmd)(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE evt);
 
 struct SCA {
     async_cmd   cmd;
+    HANDLE      evt;
     UINT 	wDevID;
     DWORD_PTR   dwParam1;
     DWORD_PTR   dwParam2;
@@ -81,7 +82,7 @@ static DWORD CALLBACK	MCI_SCAStarter(LPVOID arg)
 
     TRACE("In thread before async command (%08x,%08lx,%08lx)\n",
 	  sca->wDevID, sca->dwParam1, sca->dwParam2);
-    ret = sca->cmd(sca->wDevID, sca->dwParam1 | MCI_WAIT, sca->dwParam2);
+    ret = sca->cmd(sca->wDevID, sca->dwParam1 | MCI_WAIT, sca->dwParam2, sca->evt);
     TRACE("In thread after async command (%08x,%08lx,%08lx)\n",
 	  sca->wDevID, sca->dwParam1, sca->dwParam2);
     HeapFree(GetProcessHeap(), 0, sca);
@@ -97,7 +98,7 @@ static DWORD CALLBACK	MCI_SCAStarter(LPVOID arg)
 static	DWORD MCI_SendCommandAsync(UINT wDevID, async_cmd cmd, DWORD_PTR dwParam1,
 				   DWORD_PTR dwParam2, UINT size)
 {
-    HANDLE handle;
+    HANDLE handles[2];
     struct SCA*	sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA) + size);
 
     if (sca == 0)
@@ -117,12 +118,22 @@ static	DWORD MCI_SendCommandAsync(UINT wDevID, async_cmd cmd, DWORD_PTR dwParam1
 	sca->dwParam2 = dwParam2;
     }
 
-    if ((handle = CreateThread(NULL, 0, MCI_SCAStarter, sca, 0, NULL)) == 0) {
+    if ((sca->evt = handles[1] = CreateEventW(NULL, FALSE, FALSE, NULL)) == NULL ||
+        (handles[0] = CreateThread(NULL, 0, MCI_SCAStarter, sca, 0, NULL)) == 0) {
 	WARN("Couldn't allocate thread for async command handling, sending synchronously\n");
+        if (handles[1]) CloseHandle(handles[1]);
+        sca->evt = NULL;
 	return MCI_SCAStarter(&sca);
     }
-    SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL);
-    CloseHandle(handle);
+
+    SetThreadPriority(handles[0], THREAD_PRIORITY_TIME_CRITICAL);
+    /* wait until either:
+     * - the thread has finished (handles[0], likely an error)
+     * - init phase of async command is done (handles[1])
+     */
+    WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+    CloseHandle(handles[0]);
+    CloseHandle(handles[1]);
     return 0;
 }
 
@@ -700,7 +711,7 @@ static void WAVE_mciPlayWaitDone(WINE_MCIWAVE* wmw)
 /**************************************************************************
  * 				WAVE_mciPlay		[internal]
  */
-static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt)
+static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
 {
     LPMCI_PLAY_PARMS    lpParms = (void*)pmt;
     DWORD		end;
@@ -829,6 +840,7 @@ static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt)
     wmw->dwEventCount = 1L; /* for first buffer */
 
     TRACE("Playing (normalized) from byte=%u for %u bytes\n", wmw->dwPosition, left);
+    if (hEvent) SetEvent(hEvent);
 
     /* FIXME: this doesn't work if wmw->dwPosition != 0 */
     while (left > 0 && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
@@ -946,7 +958,7 @@ static void WAVE_mciRecordWaitDone(WINE_MCIWAVE* wmw)
 /**************************************************************************
  * 				WAVE_mciRecord			[internal]
  */
-static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt)
+static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
 {
     LPMCI_RECORD_PARMS  lpParms = (void*)pmt;
     DWORD		end;
@@ -1071,6 +1083,8 @@ static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt
 
     dwRet = waveInStart(wmw->hWave);
 
+    if (hEvent) SetEvent(hEvent);
+
     while (wmw->dwPosition < end && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
 	WAVE_mciRecordWaitDone(wmw);
     }
@@ -1627,8 +1641,8 @@ LRESULT CALLBACK MCIWAVE_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
     case MCI_OPEN_DRIVER:	return WAVE_mciOpen      (dwDevID, dwParam1, (LPMCI_WAVE_OPEN_PARMSW)  dwParam2);
     case MCI_CLOSE_DRIVER:	return WAVE_mciClose     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
     case MCI_CUE:		return WAVE_mciCue       (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
-    case MCI_PLAY:		return WAVE_mciPlay      (dwDevID, dwParam1, dwParam2);
-    case MCI_RECORD:		return WAVE_mciRecord    (dwDevID, dwParam1, dwParam2);
+    case MCI_PLAY:		return WAVE_mciPlay      (dwDevID, dwParam1, dwParam2, NULL);
+    case MCI_RECORD:		return WAVE_mciRecord    (dwDevID, dwParam1, dwParam2, NULL);
     case MCI_STOP:		return WAVE_mciStop      (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);
     case MCI_SET:		return WAVE_mciSet       (dwDevID, dwParam1, (LPMCI_SET_PARMS)         dwParam2);
     case MCI_PAUSE:		return WAVE_mciPause     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)     dwParam2);






More information about the wine-patches mailing list