http://bugs.winehq.org/show_bug.cgi?id=28413
--- Comment #14 from Jörg Höhle hoehle@users.sourceforge.net 2011-11-08 15:19:36 CST ---
I can't remember seeing protections
My memory failed me. Winmm looks much much better since the rewrite.
But that doesn't prevent concurrency troubles whenever an app needs transactions above the winmm level. Consider the following scenario:
1. PlaySound thread finishes, calls waveOutClose(hwave=0x8000) but is preempted before reaching PlaySound_Free. 2. Another thread calls waveOutOpen. It obtains the next free handle, e.g. 0x8000, which happens to be the same number as above and starts doing stuff. 3. Yet another thread calls PlaySound, thus attempts to enter WINMM_cs to abort playsound 1. Should waveOutReset be called now, it would disturb thread 2!
The MCI presents similar concurrency challenges...
Would moving waveOutReset into the section protected by WINMM_cs help? WINMM_cs is a very big lock so it may have other side effects. Introducing fine grained locks needs careful thinking to prevent dead locks. I wish I had a theorem prover ready to generally answer such questions.
Note that these days, one can consider moving waveOutClose after PlaySound_Free. That was not an option at the time Wine's winmm had to be careful not to have a device opened twice, because that was not supported by all backends (well, even now non-default devices like plughw:N may not support that).