Akihiro Sagawa : winmm: Synchronize player status and API calls.

Alexandre Julliard julliard at winehq.org
Tue May 29 16:08:31 CDT 2018


Module: wine
Branch: master
Commit: 25f610f96ad7f892e4b117b166339a529050350e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=25f610f96ad7f892e4b117b166339a529050350e

Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date:   Tue May 29 08:18:05 2018 -0500

winmm: Synchronize player status and API calls.

Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winmm/winmm.c | 46 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 9 deletions(-)

diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c
index da87be2..76807ab 100644
--- a/dlls/winmm/winmm.c
+++ b/dlls/winmm/winmm.c
@@ -1004,15 +1004,18 @@ static	BOOL	MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
                                (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
                                lpwm->mod.dwInstance, (DWORD_PTR)lphdr, 0);
             }
+            SetEvent((HANDLE)msg->wParam);
             return TRUE;
         case WINE_MSM_RESUME:
             /* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
             lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
             lpMidiStrm->status = MSM_STATUS_PLAYING;
+            SetEvent((HANDLE)msg->wParam);
             return TRUE;
         case WINE_MSM_PAUSE:
             /* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
             lpMidiStrm->status = MSM_STATUS_PAUSED;
+            SetEvent((HANDLE)msg->wParam);
             break;
 	/* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
 	 * by native mcimidi, it doesn't look like a correct one".
@@ -1387,20 +1390,49 @@ MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr,
     return ret;
 }
 
+static MMRESULT midistream_post_message_and_wait(WINE_MIDIStream* lpMidiStrm, UINT msg, LPARAM lParam)
+{
+    HANDLE hObjects[2];
+
+    hObjects[0] = CreateEventW(NULL, FALSE, FALSE, NULL);
+    if (!hObjects[0])
+        return MMSYSERR_ERROR;
+
+    if (!PostThreadMessageA(lpMidiStrm->dwThreadID, msg, (WPARAM)hObjects[0], lParam)) {
+        WARN("bad PostThreadMessage\n");
+        CloseHandle(hObjects[0]);
+        return MMSYSERR_ERROR;
+    }
+
+    if (GetCurrentThreadId() != lpMidiStrm->dwThreadID) {
+        DWORD ret;
+        hObjects[1] = lpMidiStrm->hThread;
+        ret = WaitForMultipleObjects(sizeof(hObjects)/sizeof(hObjects[0]), hObjects,
+                                     FALSE, INFINITE);
+        if (ret != WAIT_OBJECT_0) {
+            CloseHandle(hObjects[0]);
+            WARN("bad WaitForSingleObject (%u)\n", ret);
+            return MMSYSERR_ERROR;
+        }
+    }
+
+    CloseHandle(hObjects[0]);
+
+    return MMSYSERR_NOERROR;
+}
+
 /**************************************************************************
  * 				midiStreamPause			[WINMM.@]
  */
 MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
 {
     WINE_MIDIStream*	lpMidiStrm;
-    DWORD		ret = MMSYSERR_NOERROR;
 
     TRACE("(%p)!\n", hMidiStrm);
 
     if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
         return MMSYSERR_INVALHANDLE;
-    PostThreadMessageA(lpMidiStrm->dwThreadID, WINE_MSM_PAUSE, 0, 0);
-    return ret;
+    return midistream_post_message_and_wait(lpMidiStrm, WINE_MSM_PAUSE, 0);
 }
 
 /**************************************************************************
@@ -1496,14 +1528,12 @@ MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD
 MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
 {
     WINE_MIDIStream*	lpMidiStrm;
-    MMRESULT		ret = MMSYSERR_NOERROR;
 
     TRACE("(%p)!\n", hMidiStrm);
 
     if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
         return MMSYSERR_INVALHANDLE;
-    PostThreadMessageA(lpMidiStrm->dwThreadID, WINE_MSM_RESUME, 0, 0);
-    return ret;
+    return midistream_post_message_and_wait(lpMidiStrm, WINE_MSM_RESUME, 0);
 }
 
 /**************************************************************************
@@ -1512,14 +1542,12 @@ MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
 MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
 {
     WINE_MIDIStream*	lpMidiStrm;
-    MMRESULT		ret = MMSYSERR_NOERROR;
 
     TRACE("(%p)!\n", hMidiStrm);
 
     if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
         return MMSYSERR_INVALHANDLE;
-    PostThreadMessageA(lpMidiStrm->dwThreadID, WINE_MSM_STOP, 0, 0);
-    return ret;
+    return midistream_post_message_and_wait(lpMidiStrm, WINE_MSM_STOP, 0);
 }
 
 struct mm_starter




More information about the wine-cvs mailing list