http://bugs.winehq.org/show_bug.cgi?id=3930
--- Comment #18 from Damjan Jovanovic damjan.jov@gmail.com 2007-08-12 04:51:48 --- Created an attachment (id=7540) --> (http://bugs.winehq.org/attachment.cgi?id=7540) winmm test
From both the stack trace and the log it is clear that the deadlock occurs when
the callback in WAIL32.DLL calls SuspendThread(). Now if you disassemble WAIL32.DLL and look at the callback, calling SuspendThread() is the first thing it does.
The MSDN doesn't document on which thread DCB_FUNCTION callbacks get called, but it is very strict in terms of what functions the callback can call and SuspendThread() definitely isn't on the list, so I wrote a test app that calls the same WINMM.DLL functions as HEROES/WAIL32.DLL and notes the thread on which the callback is invoked.
On Windows 98: Current thread = -833637 <snip> Callback thread=-887749 hdev=82F8DCAC, wMsg=955, dwUser=0, dwParam1=0, dwParam2=0
On wine and Windows XP: Current thread = 1564 <snip> Callback thread=1564 hdev=0024B660, wMsg=955, dwUser=0, dwParam1=0, dwParam2=0
So on Windows 98, the callback is invoked on a different thread to the one that calls waveOutOpen(), while on wine and Windows XP it is the same thread. Now bearing in mind that Heroes is made for Windows 95 and doesn't work on Windows 2000, it could well be that Windows XP autodetects that the game expects Windows 9x semantics for callbacks and does them that way while doing them differently for my test, which would mean wine is calling the callback on the wrong thread.