http://bugs.winehq.org/show_bug.cgi?id=3930
--- Comment #41 from Jörg Höhle hoehle@users.sourceforge.net 2011-03-18 12:13:31 CDT --- I repeated the GetCurrentThreadId() callback test from comment #37 as testbot jobs 9892 and 9891.
There's an incredibly simple explanation of the behaviour observed since w2k that does not require QueueUserAPC() or other delayed procedure calls (DP): let the application thread execute the player! Obviously then, callbacks invoked synchronously will be executed in the app's thread, which is the test result for systems since w2k.
Execution in the app's thread is not unknown to Wine, e.g. MCI_PLAY does that with the MCI_WAIT flag in mciwave and mciseq.
From a system reliability perspective, hijacking the app's thread is a sensible
move on the side of MS, as by killing the one thread (or process) you remove everything it does, hence the rest of the system can continue to work unaffected.
From a compatibility POV, this is a bad move.
If since w2k calls like midiStreamRestart() and midiStreamOut() are not asynchronous messages to a concurrently running player and instead drive the player loop on the calling thread (= the application one's), then I can imagine a whole class of programs that worked on w9x but hang on newer systems -- e.g. Heroes, says comment #18. Not all programs would hang though, those designed around message dispatching delivered to the app's message queue have a good chance of working with recursive invocations of Wait/Peek/DispatchMessageA() by a winmm player executing in the application's thread.
As far as Wine is concerned, I'd favour the w9x behaviour: have the multimedia players sit in their own thread, even though a proper design causes me headaches with concurrency and locking issues.
Under this perspective, it looks like an error when player loops that execute synchronously in the app's thread (like all MCI players, e.g. MCIAVI) never drain and DispatchMessageA() the app's message queue -- the app may dead-lock when expected callbacks are not invoked. Is this perhaps an explanation to the bugs listed in bug #21060, comment #2?