http://bugs.winehq.org/show_bug.cgi?id=23756
--- Comment #8 from Jörg Höhle hoehle@users.sourceforge.net 2010-12-16 16:46:35 CST --- The main process (tid 0009) issues midiStreamStop which sends MSM_STOP to the player thread via MMSYSTEM_MidiStream_PostMessage. The player thread (typical tid 0019) then executes midiOutReset() and DriverCallback(MOM_DONE) for all 5 headers. This is a function callback and that's why things get interesting. The app callback, called on the players thread, calls midiOutUnprepareHeader() every time and additionally midiStreamClose() after the last one...
midiStreamClose() calls (midiStreamStop() and) sends the WM_QUIT message to the player thread via the known MMSYSTEM_MidiStream_PostMessage -- but the callback is still executing within the player thread! So the player thread 0019 hangs, waiting for lpMidiStrm->hEvent to be acknowledged by the player thread -- itself.
More precisely, hEvent was somehow signaled, but that's an auto-reset event and the "system automatically resets the event state to nonsignaled after a *single* waiting thread has been released" [MSDN]. The awakened thread is 0009, which has been waiting for this same hEvent as the answer to MSM_STOP above.
So perhaps unlike bug #3930, the main application thread continues to run. Only the player is hung, and the callback never completed. What follows (MCI error, MIDI only played once) is likely a consequence of that bad state.
Note that the app is broken because MSDN disallows using the multimedia API from within callbacks, but nobody cares when it works often enough.
So this is another case where the code is not re-entrant, although it's unclear to me whether it should be. Callbacks could as well be issued from a distinct thread (but see bug #3930, comment #37 about MOM_DONE).