On Mon, Sep 16, 2019 at 03:44:32PM -0300, Martin Pieuchot wrote: > On 16/09/19(Mon) 19:31, Alexandre Ratchov wrote: > > On Sun, Sep 15, 2019 at 03:01:36PM -0300, Martin Pieuchot wrote: > > > On 29/08/19(Thu) 10:52, Alexandre Ratchov wrote: > > > > The diff below allows to specifiy "an alternate device" to use in case > > > > the audio device is disconnected. If so, programs continue playing > > > > using the other device. > > > > > > > > For instance, if dmesg contains: > > > > > > > > audio0 at azalia0 > > > > audio1 at uaudio0 > > > > > > > > and /etc/rc.conf.local contains: > > > > > > > > sndiod_flags=-f rsnd/0 -F rsnd/1 > > > > > > > > then sndiod will try to use the usb device by default. If it's > > > > disconnected, programs continue using the internal one. Note that > > > > there's no way to detect that the usb device is reconnected; > > > > > > Instead of doing a open/reopen dance in userland, which is inherently > > > racy, did you consider introducing a driver abstracting the various > > > audio(4) drivers attached? I'm thinking of something like wsmux(4) for > > > audio. This should allow us to transparently attach/detach usb audio > > > devices. > > > > I don't see any race conditions: once a device disappears, it is > > closed and another one is opened in place. This only relies on calls > > to open() and close() which are not racy. Unlike with hotplug(4), > > there's no concurency between multiple code-paths; it's all > > sequencial. > > I understand the logic for closing an existing device, but what about > plugging a new one? I understand that this is not the scope of the > diff, I wondering if that would fit in the model you're suggesting. > > It is just a matter of sending SIGHUP, so I could fake that when > uaudio(4) attaches for example?
Yes. That's the best we can do with "unix file open/close semantics" only. Going further, if desired, would require some kind of kernel support. There's a full range of "clever" and complicated ways to handle hot-plugging automatically (and to configure it!). I don't know what's the best one, some experimenting is needed first. > Regarding the race I was talking about, doesn't dev_reopen() close the > current device before trying to open a new one, possibly finding an > incompatible device or failing to open it? What happens in this case? After a SIGHUP, if the new device is incompatible, the old one is reopened and sound continues. Now I understand your remark: oops! close() and open() are called in the wrong order, so another process could steal the device. I'll fix that. > > I've considered the wsmux-style device for audio. Multiple audio > > devices can't be combined, so the audio mux device would be a switch > > between the devices, which is roughly what the diff does. > > > > Switching between devices, when possible, is not trivial, because the > > state of one device must be restored on another device. It may require > > channel mapping and/or format conversions, in case the devices don't > > have the same capabilities. We don't want such complicated code to run > > with full kernel privileges and to have access to all the physical > > memory. FWIW, this was one of the reasons for moving the audio > > sub-system completely to user-space, leaving in the kernel only the > > code to access the hardware. > > I understand. > > Another question, if a machine has multiple audio devices, including an > USB one, can't we assume that we should try this one first? Or could a > choice mechanism like kern.timecounter with default value could be > implemented to make this new feature work out of the box? Almost. The reverse attaching order seems to cover most practical use cases. If the user coonects a USB device, it's probably because he wants to use it, so it would make sense for it to be tried first. But a choice mechanism seems necessary in certain cases. For instance "pro" audio interfaces need to be handled separately; certain USB devices (ex. webcams) come with an unused audio interface that the user may want to skip. > > Finally, is there any downside of having a smaller DEFAULT_ROUND? No. FWIW, the large default block and buffer sizes used to be necessary 10+ years ago because MP kernels could delay interrupts for more than a audio block which used to confuse azalia(4) and envy(4) permanently. Now drivers are resilient to interrupt loss and any block size could be used. Recent MP kernels behave better.
