After trying to implement the alsa mixer I came across a problem: If winmm is unloading, a deadlock could occur if during unloading it's waiting for another thread.
In winmm itself this isn't much of a problem: there aren't any threads.
However, the drivers used by winmm may have threads, and if the application doesn't shut down their drivers properly, it could be possible that a deadlock occurs when the drivers unload because winmm unloads.
For that reason I propose to add a flag that's passed to the sound drivers that signals a shutdown in DLL_DETACH context, so that drivers can choose to call TerminateThread instead of waiting tidily for the thread to finish running.
It's not pretty, but I don't see another way how to make sure that deadlocks won't occur when unloading winmm. I'm open for other suggestions though.
Maarten
Maarten Lankhorst schrieb:
After trying to implement the alsa mixer I came across a problem: If winmm is unloading, a deadlock could occur if during unloading it's waiting for another thread.
In winmm itself this isn't much of a problem: there aren't any threads.
However, the drivers used by winmm may have threads, and if the application doesn't shut down their drivers properly, it could be possible that a deadlock occurs when the drivers unload because winmm unloads.
For that reason I propose to add a flag that's passed to the sound drivers that signals a shutdown in DLL_DETACH context, so that drivers can choose to call TerminateThread instead of waiting tidily for the thread to finish running.
It's not pretty, but I don't see another way how to make sure that deadlocks won't occur when unloading winmm. I'm open for other suggestions though.
AFAIK you get the DRVM_EXIT message only when winmm is unloading. Alternatively you could do it in response to the DRV_CLOSE message which winmm sends just before it tries to unload the driver.
That said I don't see how your code in ALSA_MixerExit() could deadlock. It effectively tries to exit the thread the same way as MIX_Close, doesn't it? So the thread should exit safely. Imo the question is rather why the thread isn't exiting and you are waiting forever. Forcibly calling TerminateThread just covers the problem.
Peter Beutner schreef:
AFAIK you get the DRVM_EXIT message only when winmm is unloading. Alternatively you could do it in response to the DRV_CLOSE message which winmm sends just before it tries to unload the driver.
That said I don't see how your code in ALSA_MixerExit() could deadlock. It effectively tries to exit the thread the same way as MIX_Close, doesn't it? So the thread should exit safely. Imo the question is rather why the thread isn't exiting and you are waiting forever. Forcibly calling TerminateThread just covers the problem
The deadlock isn't in the alsa code, it's in the kernel code: Kernel holds thread lock and calls closing winmm code, closing code closes mixer driver, mixer closing waits on thread, thread waits till it can hold thread lock -> deadlock.
Under normal circumstances, MIX_Open will be called as often as MIX_Close is. If the programmer is lazy and never closes its handle, MIX_Close will be called when winmm is shutting down, in that case I would want to pass some kind of signal that it can't wait on thread exit because it would deadlock. The thread should still be terminated in MIX_Close then, so unless you pass a flag that application hasn't shut down the device driver properly, this potentially causes the deadlock to occur. The thread termination in ALSA_MixerExit should never happen: it would indicate a bug in winmm that it doesn't close mixer before releasing it, but I put it in as a safeguard, that's why it will print an ERR too.
Maarten
Maarten Lankhorst schrieb:
Peter Beutner schreef:
AFAIK you get the DRVM_EXIT message only when winmm is unloading. Alternatively you could do it in response to the DRV_CLOSE message which winmm sends just before it tries to unload the driver.
That said I don't see how your code in ALSA_MixerExit() could deadlock. It effectively tries to exit the thread the same way as MIX_Close, doesn't it? So the thread should exit safely. Imo the question is rather why the thread isn't exiting and you are waiting forever. Forcibly calling TerminateThread just covers the problem
The deadlock isn't in the alsa code, it's in the kernel code: Kernel holds thread lock and calls closing winmm code, closing code closes mixer driver, mixer closing waits on thread, thread waits till it can hold thread lock -> deadlock.
Under normal circumstances, MIX_Open will be called as often as MIX_Close is. If the programmer is lazy and never closes its handle, MIX_Close will be called when winmm is shutting down, in that case I
Are you sure about this? I don't think winmm calls MIX_Close on its own when it shuts down and the device is still open. It only sends the DRVM_EXIT message(and throws out a FIXME). So there shouldn't be a deadlock in MIX_Close() and in ALSA_MixerExit() you can always call TerminateThread when the thread still exists.