Why doesn't mixer control (values) have some kind of locking mechanism? (mutex?)
Tom Yan
tom.ty89 at gmail.com
Thu Aug 6 20:45:55 CEST 2020
On Fri, 7 Aug 2020 at 01:19, Takashi Sakamoto <o-takashi at sakamocchi.jp> wrote:
>
>
> In your case, SNDRV_CTL_IOCTL_ELEM_LOCK looks 'write-lock', therefore
> any userspace applications can do read operation to the control element
> locked by the other processes.
>
> To solve the issue, the pair of read/write operations should be done
> between lock/unlock operations. I can consider about two cases.
>
> A case is that all of applications implements the above. This is
> already proposed. The case is that the world is universe.
>
> +-----------+-----------+
> | process A | process B |
> +-----------+-----------+
> | lock | |
> | read | |
> | |lock(EPERM)| reschedule lock/get/put/unlock actions
> | write | |
> | |lock(EPERM)| reschedule lock/get/put/unlock actions
> | unlock | |
> | | lock |
> | | read | calculate for new value
> | | write |
> | | unlock |
> +-----------+-----------+
>
> Another case is that a part of application implements the above. Let
> me drill down the case into two cases. These cases are realistic
> (sign...):
>
> +-----------+------------+
> | process A | process B |
> +-----------+------------+
> | lock | |
> | read | |
> | write | |
> | | read | calculate for new value
> | |write(EPERM)|
> | unlock | |
> | | write | <- expected value
> +-----------+------------+
>
> +-----------+------------+
> | process A | process B |
> +-----------+------------+
> | lock | |
> | read | |
> | | read | calculate for new value
> | write | |
> | |write(EPERM)|
> | unlock | |
> | | write | <- unexpected value
> +-----------+------------+
>
> The lock/unlock mechanism is not perfect solution as long as any
> applications perform like the process.
>
> If we can expect the most of applications to be back to read operation
> at failure of write operation, thing goes well.
>
> +-----------+------------+
> | process A | process B |
> +-----------+------------+
> | lock | |
> | read | |
> | | read | calculate for new value
> | write | |
> | |write(EPERM)|
> | unlock | |
> | | read | calculate for new value
> | | write | <- expected value
> +-----------+------------+
>
Oh you were saying, while it is a "write lock in nature", if all the
processes considered/involved make use of it (properly, by attempting
to lock before *reading*), it would work like a "full" lock. Sorry I
wasn't thinking straight.
And I guess there's no point in changing it into a "real" full lock in
the kernel anyway as that won't prevent whatever that doesn't make use
of it race with each other.
Okay so I suppose that means we can/should at least fix amixer with it
for now and see if we can/want to get something better into the
kernel. (I am in no position to comment on whether we should do
compare-and-swap as I don't know if it's a good idea programmatically
speaking, or if there's a huge price in any aspect; all I know is that
it *looks* more neat.)
Thanks a lot! Should I file an issue additionally in the alsa-utils
github repo btw?
>
> Thanks
>
> Takashi Sakamoto
More information about the Alsa-devel
mailing list