Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1b115760
Commit
1b115760
authored
Feb 06, 2012
by
Jörg Höhle
Committed by
Alexandre Julliard
Feb 17, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winmm: Avoid using SuspendThread, it can hang Wine.
parent
d2f49c33
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
101 additions
and
114 deletions
+101
-114
winmm.c
dlls/winmm/winmm.c
+101
-114
No files found.
dlls/winmm/winmm.c
View file @
1b115760
...
...
@@ -957,6 +957,8 @@ typedef struct WINE_MIDIStream {
#define WINE_MSM_HEADER (WM_USER+0)
#define WINE_MSM_STOP (WM_USER+1)
#define WINE_MSM_PAUSE (WM_USER+2)
#define WINE_MSM_RESUME (WM_USER+3)
/**************************************************************************
* MMSYSTEM_GetMidiStream [internal]
...
...
@@ -1006,34 +1008,41 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
LPMIDIHDR
lpMidiHdr
;
LPMIDIHDR
*
lpmh
;
LPBYTE
lpData
;
switch
(
msg
->
message
)
{
case
WM_QUIT
:
SetEvent
(
lpMidiStrm
->
hEvent
);
return
FALSE
;
case
WINE_MSM_STOP
:
TRACE
(
"STOP
\n
"
);
/* this is not quite what MS doc says... */
midiOutReset
(
lpMidiStrm
->
hDevice
);
/* empty list of already submitted buffers */
for
(
lpMidiHdr
=
lpMidiStrm
->
lpMidiHdr
;
lpMidiHdr
;
)
{
LPMIDIHDR
lphdr
=
lpMidiHdr
;
lpMidiHdr
=
lpMidiHdr
->
lpNext
;
lphdr
->
dwFlags
|=
MHDR_DONE
;
lphdr
->
dwFlags
&=
~
MHDR_INQUEUE
;
DriverCallback
(
lpwm
->
mod
.
dwCallback
,
lpMidiStrm
->
wFlags
,
(
HDRVR
)
lpMidiStrm
->
hDevice
,
MM_MOM_DONE
,
lpwm
->
mod
.
dwInstance
,
(
DWORD_PTR
)
lphdr
,
0
);
}
lpMidiStrm
->
lpMidiHdr
=
0
;
SetEvent
(
lpMidiStrm
->
hEvent
);
break
;
case
WINE_MSM_HEADER
:
/* sets initial tick count for first MIDIHDR */
if
(
!
lpMidiStrm
->
dwStartTicks
)
lpMidiStrm
->
dwStartTicks
=
GetTickCount
();
BOOL
paused
=
FALSE
;
for
(;;)
{
switch
(
msg
->
message
)
{
case
WM_QUIT
:
SetEvent
(
lpMidiStrm
->
hEvent
);
return
FALSE
;
case
WINE_MSM_STOP
:
TRACE
(
"STOP
\n
"
);
/* this is not quite what MS doc says... */
midiOutReset
(
lpMidiStrm
->
hDevice
);
/* empty list of already submitted buffers */
for
(
lpMidiHdr
=
lpMidiStrm
->
lpMidiHdr
;
lpMidiHdr
;
)
{
LPMIDIHDR
lphdr
=
lpMidiHdr
;
lpMidiHdr
=
lpMidiHdr
->
lpNext
;
lphdr
->
dwFlags
|=
MHDR_DONE
;
lphdr
->
dwFlags
&=
~
MHDR_INQUEUE
;
DriverCallback
(
lpwm
->
mod
.
dwCallback
,
lpMidiStrm
->
wFlags
,
(
HDRVR
)
lpMidiStrm
->
hDevice
,
MM_MOM_DONE
,
lpwm
->
mod
.
dwInstance
,
(
DWORD_PTR
)
lphdr
,
0
);
}
lpMidiStrm
->
lpMidiHdr
=
0
;
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
;
/* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
* by native mcimidi, it doesn't look like a correct one".
* this trick allows to throw it away... but I don't like it.
...
...
@@ -1061,60 +1070,62 @@ 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..;...#..|.
* 3b 4c 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 ;L..#^..;...#.|.
*/
lpMidiHdr
=
(
LPMIDIHDR
)
msg
->
lParam
;
lpData
=
(
LPBYTE
)
lpMidiHdr
->
lpData
;
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
,
lpMidiHdr
->
dwBytesRecorded
,
lpMidiHdr
->
dwBufferLength
,
lpMidiHdr
->
dwFlags
,
msg
->
wParam
);
case
WINE_MSM_HEADER
:
/* sets initial tick count for first MIDIHDR */
if
(
!
lpMidiStrm
->
dwStartTicks
)
lpMidiStrm
->
dwStartTicks
=
GetTickCount
();
lpMidiHdr
=
(
LPMIDIHDR
)
msg
->
lParam
;
lpData
=
(
LPBYTE
)
lpMidiHdr
->
lpData
;
TRACE
(
"Adding %s lpMidiHdr=%p [lpData=0x%p dwBytesRecorded=%u/%u dwFlags=0x%08x size=%lu]
\n
"
,
(
lpMidiHdr
->
dwFlags
&
MHDR_ISSTRM
)
?
"stream"
:
"regular"
,
lpMidiHdr
,
lpData
,
lpMidiHdr
->
dwBytesRecorded
,
lpMidiHdr
->
dwBufferLength
,
lpMidiHdr
->
dwFlags
,
msg
->
wParam
);
#if 0
/* dumps content of lpMidiHdr->lpData
* 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) {
DWORD i;
BYTE ch;
for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++)
printf("%02x ", lpData[dwToGo + i]);
for (; i < 16; i++)
printf(" ");
for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) {
ch = lpData[dwToGo + i];
printf("%c", (ch >= 0x20 && ch <= 0x7F) ? ch : '.');
}
printf("\n");
}
/* dumps content of lpMidiHdr->lpData
* FIXME: there should be a debug routine somewhere that already does this
*/
for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) {
DWORD i;
BYTE ch;
for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++)
printf("%02x ", lpData[dwToGo + i]);
for (; i < 16; i++)
printf(" ");
for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) {
ch = lpData[dwToGo + i];
printf("%c", (ch >= 0x20 && ch <= 0x7F) ? ch : '.');
}
printf("\n");
}
#endif
if
(((
LPMIDIEVENT
)
lpData
)
->
dwStreamID
!=
0
&&
((
LPMIDIEVENT
)
lpData
)
->
dwStreamID
!=
0xFFFFFFFF
&&
((
LPMIDIEVENT
)
lpData
)
->
dwStreamID
!=
(
DWORD
)
lpMidiStrm
)
{
FIXME
(
"Dropping bad %s lpMidiHdr (streamID=%08x)
\n
"
,
(
lpMidiHdr
->
dwFlags
&
MHDR_ISSTRM
)
?
"stream"
:
"regular"
,
((
LPMIDIEVENT
)
lpData
)
->
dwStreamID
);
lpMidiHdr
->
dwFlags
|=
MHDR_DON
E
;
lpMidiHdr
->
dwFlags
&=
~
MHDR_INQUEU
E
;
DriverCallback
(
lpwm
->
mod
.
dwCallback
,
lpMidiStrm
->
wFlags
,
(
HDRVR
)
lpMidiStrm
->
hDevice
,
MM_MOM_DONE
,
lpwm
->
mod
.
dwInstance
,
(
DWORD_PTR
)
lpMidiHdr
,
0
);
break
;
}
for
(
lpmh
=
&
lpMidiStrm
->
lpMidiHdr
;
*
lpmh
;
lpmh
=
&
(
*
lpmh
)
->
lpNext
)
;
*
lpmh
=
lpMidiHdr
;
lpMidiHdr
=
(
LPMIDIHDR
)
msg
->
lParam
;
lpMidiHdr
->
lpNext
=
0
;
lpMidiHdr
->
dwFlags
|=
MHDR_INQUEUE
;
lpMidiHdr
->
dwFlags
&=
~
MHDR_DONE
;
break
;
default:
FIXME
(
"Unknown message %d
\n
"
,
msg
->
message
)
;
break
;
if
(((
LPMIDIEVENT
)
lpData
)
->
dwStreamID
!=
0
&&
((
LPMIDIEVENT
)
lpData
)
->
dwStreamID
!=
0xFFFFFFFF
&&
((
LPMIDIEVENT
)
lpData
)
->
dwStreamID
!=
(
DWORD
)
lpMidiStrm
)
{
FIXME
(
"Dropping bad %s lpMidiHdr (streamID=%08x)
\n
"
,
(
lpMidiHdr
->
dwFlags
&
MHDR_ISSTRM
)
?
"stream"
:
"regular"
,
((
LPMIDIEVENT
)
lpData
)
->
dwStreamID
);
lpMidiHdr
->
dwFlags
&=
~
MHDR_INQUEU
E
;
lpMidiHdr
->
dwFlags
|=
MHDR_DON
E
;
DriverCallback
(
lpwm
->
mod
.
dwCallback
,
lpMidiStrm
->
wFlags
,
(
HDRVR
)
lpMidiStrm
->
hDevice
,
MM_MOM_DONE
,
lpwm
->
mod
.
dwInstance
,
(
DWORD_PTR
)
lpMidiHdr
,
0
);
break
;
}
lpMidiHdr
->
lpNext
=
0
;
for
(
lpmh
=
&
lpMidiStrm
->
lpMidiHdr
;
*
lpmh
;
lpmh
=
&
(
*
lpmh
)
->
lpNext
)
;
*
lpmh
=
lpMidiHdr
;
break
;
default:
FIXME
(
"Unknown message %d
\n
"
,
msg
->
message
)
;
break
;
}
if
(
!
paused
)
return
TRUE
;
GetMessageA
(
msg
,
0
,
0
,
0
)
;
}
return
TRUE
;
}
/**************************************************************************
...
...
@@ -1335,8 +1346,8 @@ MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
/* wait for thread to have started, and for its queue to be created */
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
"
,
*
lpuDeviceID
,
lpwm
->
mld
.
uDeviceID
,
*
lphMidiStrm
,
ret
,
lpMidiStrm
);
...
...
@@ -1392,14 +1403,9 @@ MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
TRACE
(
"(%p)!
\n
"
,
hMidiStrm
);
if
(
!
MMSYSTEM_GetMidiStream
(
hMidiStrm
,
&
lpMidiStrm
,
NULL
))
{
ret
=
MMSYSERR_INVALHANDLE
;
}
else
{
if
(
SuspendThread
(
lpMidiStrm
->
hThread
)
==
0xFFFFFFFF
)
{
ERR
(
"bad Suspend (%d)
\n
"
,
GetLastError
());
ret
=
MMSYSERR_ERROR
;
}
}
if
(
!
MMSYSTEM_GetMidiStream
(
hMidiStrm
,
&
lpMidiStrm
,
NULL
))
return
MMSYSERR_INVALHANDLE
;
MMSYSTEM_MidiStream_PostMessage
(
lpMidiStrm
,
WINE_MSM_PAUSE
,
0
,
0
);
return
ret
;
}
...
...
@@ -1493,24 +1499,9 @@ MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
TRACE
(
"(%p)!
\n
"
,
hMidiStrm
);
if
(
!
MMSYSTEM_GetMidiStream
(
hMidiStrm
,
&
lpMidiStrm
,
NULL
))
{
ret
=
MMSYSERR_INVALHANDLE
;
}
else
{
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
;
}
}
if
(
!
MMSYSTEM_GetMidiStream
(
hMidiStrm
,
&
lpMidiStrm
,
NULL
))
return
MMSYSERR_INVALHANDLE
;
MMSYSTEM_MidiStream_PostMessage
(
lpMidiStrm
,
WINE_MSM_RESUME
,
0
,
0
);
return
ret
;
}
...
...
@@ -1524,13 +1515,9 @@ MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
TRACE
(
"(%p)!
\n
"
,
hMidiStrm
);
if
(
!
MMSYSTEM_GetMidiStream
(
hMidiStrm
,
&
lpMidiStrm
,
NULL
))
{
ret
=
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
);
}
if
(
!
MMSYSTEM_GetMidiStream
(
hMidiStrm
,
&
lpMidiStrm
,
NULL
))
return
MMSYSERR_INVALHANDLE
;
MMSYSTEM_MidiStream_PostMessage
(
lpMidiStrm
,
WINE_MSM_STOP
,
0
,
0
);
return
ret
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment