Commit 1b115760 authored by Jörg Höhle's avatar Jörg Höhle Committed by Alexandre Julliard

winmm: Avoid using SuspendThread, it can hang Wine.

parent d2f49c33
...@@ -957,6 +957,8 @@ typedef struct WINE_MIDIStream { ...@@ -957,6 +957,8 @@ typedef struct WINE_MIDIStream {
#define WINE_MSM_HEADER (WM_USER+0) #define WINE_MSM_HEADER (WM_USER+0)
#define WINE_MSM_STOP (WM_USER+1) #define WINE_MSM_STOP (WM_USER+1)
#define WINE_MSM_PAUSE (WM_USER+2)
#define WINE_MSM_RESUME (WM_USER+3)
/************************************************************************** /**************************************************************************
* MMSYSTEM_GetMidiStream [internal] * MMSYSTEM_GetMidiStream [internal]
...@@ -1006,7 +1008,9 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI ...@@ -1006,7 +1008,9 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
LPMIDIHDR lpMidiHdr; LPMIDIHDR lpMidiHdr;
LPMIDIHDR* lpmh; LPMIDIHDR* lpmh;
LPBYTE lpData; LPBYTE lpData;
BOOL paused = FALSE;
for (;;) {
switch (msg->message) { switch (msg->message) {
case WM_QUIT: case WM_QUIT:
SetEvent(lpMidiStrm->hEvent); SetEvent(lpMidiStrm->hEvent);
...@@ -1028,12 +1032,17 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI ...@@ -1028,12 +1032,17 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
} }
lpMidiStrm->lpMidiHdr = 0; lpMidiStrm->lpMidiHdr = 0;
SetEvent(lpMidiStrm->hEvent); SetEvent(lpMidiStrm->hEvent);
return TRUE;
case WINE_MSM_RESUME:
/* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
SetEvent(lpMidiStrm->hEvent);
return TRUE;
case WINE_MSM_PAUSE:
/* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
paused = TRUE;
SetEvent(lpMidiStrm->hEvent);
break; break;
case WINE_MSM_HEADER:
/* sets initial tick count for first MIDIHDR */
if (!lpMidiStrm->dwStartTicks)
lpMidiStrm->dwStartTicks = GetTickCount();
/* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent /* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
* by native mcimidi, it doesn't look like a correct one". * by native mcimidi, it doesn't look like a correct one".
* this trick allows to throw it away... but I don't like it. * this trick allows to throw it away... but I don't like it.
...@@ -1061,16 +1070,19 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI ...@@ -1061,16 +1070,19 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
* 48 00 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 H..#x..;...#..|. * 48 00 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 H..#x..;...#..|.
* 3b 4c 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 ;L..#^..;...#.|. * 3b 4c 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 ;L..#^..;...#.|.
*/ */
case WINE_MSM_HEADER:
/* sets initial tick count for first MIDIHDR */
if (!lpMidiStrm->dwStartTicks)
lpMidiStrm->dwStartTicks = GetTickCount();
lpMidiHdr = (LPMIDIHDR)msg->lParam; lpMidiHdr = (LPMIDIHDR)msg->lParam;
lpData = (LPBYTE)lpMidiHdr->lpData; lpData = (LPBYTE)lpMidiHdr->lpData;
TRACE("Adding %s lpMidiHdr=%p [lpData=0x%p dwBytesRecorded=%u/%u dwFlags=0x%08x size=%lu]\n", TRACE("Adding %s lpMidiHdr=%p [lpData=0x%p dwBytesRecorded=%u/%u dwFlags=0x%08x size=%lu]\n",
(lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", lpMidiHdr, (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", lpMidiHdr,
lpMidiHdr, lpMidiHdr->dwBytesRecorded, lpMidiHdr->dwBufferLength, lpData, lpMidiHdr->dwBytesRecorded, lpMidiHdr->dwBufferLength,
lpMidiHdr->dwFlags, msg->wParam); lpMidiHdr->dwFlags, msg->wParam);
#if 0 #if 0
/* dumps content of lpMidiHdr->lpData /* dumps content of lpMidiHdr->lpData
* FIXME: there should be a debug routine somewhere that already does this * FIXME: there should be a debug routine somewhere that already does this
* I hate spreading this type of shit all around the code
*/ */
for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) { for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) {
DWORD i; DWORD i;
...@@ -1093,8 +1105,8 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI ...@@ -1093,8 +1105,8 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
FIXME("Dropping bad %s lpMidiHdr (streamID=%08x)\n", FIXME("Dropping bad %s lpMidiHdr (streamID=%08x)\n",
(lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular",
((LPMIDIEVENT)lpData)->dwStreamID); ((LPMIDIEVENT)lpData)->dwStreamID);
lpMidiHdr->dwFlags |= MHDR_DONE;
lpMidiHdr->dwFlags &= ~MHDR_INQUEUE; lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
lpMidiHdr->dwFlags |= MHDR_DONE;
DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags, DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
(HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE, (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
...@@ -1102,19 +1114,18 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI ...@@ -1102,19 +1114,18 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
break; break;
} }
lpMidiHdr->lpNext = 0;
for (lpmh = &lpMidiStrm->lpMidiHdr; *lpmh; lpmh = &(*lpmh)->lpNext); for (lpmh = &lpMidiStrm->lpMidiHdr; *lpmh; lpmh = &(*lpmh)->lpNext);
*lpmh = lpMidiHdr; *lpmh = lpMidiHdr;
lpMidiHdr = (LPMIDIHDR)msg->lParam;
lpMidiHdr->lpNext = 0;
lpMidiHdr->dwFlags |= MHDR_INQUEUE;
lpMidiHdr->dwFlags &= ~MHDR_DONE;
break; break;
default: default:
FIXME("Unknown message %d\n", msg->message); FIXME("Unknown message %d\n", msg->message);
break; break;
} }
if (!paused)
return TRUE; return TRUE;
GetMessageA(msg, 0, 0, 0);
}
} }
/************************************************************************** /**************************************************************************
...@@ -1335,8 +1346,8 @@ MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID, ...@@ -1335,8 +1346,8 @@ MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
/* wait for thread to have started, and for its queue to be created */ /* wait for thread to have started, and for its queue to be created */
WaitForSingleObject(lpMidiStrm->hEvent, INFINITE); WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
/* start in paused mode */
SuspendThread(lpMidiStrm->hThread); MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_PAUSE, 0, 0);
TRACE("=> (%u/%d) hMidi=%p ret=%d lpMidiStrm=%p\n", TRACE("=> (%u/%d) hMidi=%p ret=%d lpMidiStrm=%p\n",
*lpuDeviceID, lpwm->mld.uDeviceID, *lphMidiStrm, ret, lpMidiStrm); *lpuDeviceID, lpwm->mld.uDeviceID, *lphMidiStrm, ret, lpMidiStrm);
...@@ -1392,14 +1403,9 @@ MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm) ...@@ -1392,14 +1403,9 @@ MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
TRACE("(%p)!\n", hMidiStrm); TRACE("(%p)!\n", hMidiStrm);
if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) { if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
ret = MMSYSERR_INVALHANDLE; return MMSYSERR_INVALHANDLE;
} else { MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_PAUSE, 0, 0);
if (SuspendThread(lpMidiStrm->hThread) == 0xFFFFFFFF) {
ERR("bad Suspend (%d)\n", GetLastError());
ret = MMSYSERR_ERROR;
}
}
return ret; return ret;
} }
...@@ -1493,24 +1499,9 @@ MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm) ...@@ -1493,24 +1499,9 @@ MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
TRACE("(%p)!\n", hMidiStrm); TRACE("(%p)!\n", hMidiStrm);
if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) { if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
ret = MMSYSERR_INVALHANDLE; return MMSYSERR_INVALHANDLE;
} else { MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_RESUME, 0, 0);
DWORD ret;
/* since we increase the thread suspend count on each midiStreamPause
* there may be a need for several ResumeThread
*/
do {
ret = ResumeThread(lpMidiStrm->hThread);
} while (ret != 0xFFFFFFFF && ret > 1);
if (ret == 0xFFFFFFFF) {
ERR("bad Resume (%d)\n", GetLastError());
ret = MMSYSERR_ERROR;
} else {
lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
}
}
return ret; return ret;
} }
...@@ -1524,13 +1515,9 @@ MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm) ...@@ -1524,13 +1515,9 @@ MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
TRACE("(%p)!\n", hMidiStrm); TRACE("(%p)!\n", hMidiStrm);
if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) { if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
ret = MMSYSERR_INVALHANDLE; return MMSYSERR_INVALHANDLE;
} else {
/* in case stream has been paused... FIXME is the current state correct ? */
midiStreamRestart(hMidiStrm);
MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_STOP, 0, 0); MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_STOP, 0, 0);
}
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment