Hot-unplugging a sound device, such as a USB sound card, whilst being
consumed by an application, results in the parent bus going into an
infinite loop (and as a result, becoming unusable) until either the
application closes the device's file descriptor, or the channel
automatically times out after hw.snd.timeout seconds. In the case of a
detach however, the timeout approach is still not ideal, since we want
all resources to be released immediatelly, without waiting for N seconds
until we can use the bus again.
The timeout mechanism works by calling chn_sleep() in chn_read() and
chn_write() (see pcm/channel.c) in order to send the thread to sleep,
using cv_timedwait_sig(). Since chn_sleep() sets the CHN_F_SLEEPING flag
while waiting for cv_timedwait_sig() to return, we can test this flag in
pcm_unregister() (called during detach) and wakeup the sleeping
thread(s) to immediately kill the channel(s) being consumed.
To avoid a use-after-free bug when destroying the clone(s) (as a result
of destroying them before the sleeping threads have drained), block
pcm_unregister() using snd_clone_sleep() until the clone refcount
reaches 0, at which point the thread will be woken up by
snd_clone_wakeup() and pcm_unregister() will resume execution.
While here, remove snddev_info's inprog field, as well as pcm_inprog(),
as they are no longer used.
Sponsored by: The FreeBSD Foundation
MFC after: 3 weeks
PR: 194727