On 07/27/2015 12:27 PM, Takashi Iwai wrote:
On Sat, 25 Jul 2015 13:54:00 +0200, Takashi Sakamoto wrote:
ALSA control character devices doesn't release blocking state for read(2) operations when a file descriptor corresponding to the character device is closed by close(2). This is due to a blocking loop of snd_ctl_read() has no breaking point for this event.
Additionally, the read(2) operation reports EBADFD when executed in a state of unsubscription. On the other hand, this operation continue to be blocked after unsubscribe operation. In this case, the read(2) operation should return with EBADFD.
Furthermore, poll(2) operation for the character device can report some events after close(2).
This commit solves these issues, by adding flush file operation. The file descriptor becomes unsubscribed state after close(2) operation. Then, read(2) and poll(2) operations return with expected results.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp
Thanks for spotting out the problem and the patch. I guess your patch would work in most cases correctly.
Is it really a problem? I'd say it's the expected behavior. What close does is destroys the mapping between the process local fd and the global struct file. It does not abort any pending blocking operations. If you want to wakeup a blocking operation you need to send a signal to the thread.
One thing I'm not sure is the case where the file descriptor is copied. Is the flush op called only if one of the multiple processes is closed, or is it after all fps closed? In the former case, this might be a problem.
Should be on every close. Especially with close-on-exec this quickly becomes a problem.