libc_vfs: don't suspend in 'notify_read_ready()'

When 'notify_read_ready()' is called during 'select()' and fails,
suspending can cause a deadlock when the libc IO response handler becomes
active and calls 'select_notify()', which tries to acquire the
'select callback list lock', which is already acquired by the suspended
'select()' call.

It seems possible to ignore a failed 'notify_read_ready()' call instead of
suspending. When the VFS plugin calls the IO handler later when the
notification request can be processed, the 'select_notify()' call of the
libc IO response handler will eventually call 'notify_read_ready()' again.

Fixes #2970
This commit is contained in:
Christian Prochaska 2018-09-07 19:01:48 +02:00 committed by Christian Helmuth
parent 473fde900b
commit 35f61475f5

View File

@ -157,16 +157,13 @@ namespace Libc {
void notify_read_ready(Vfs::Vfs_handle *handle)
{
struct Check : Libc::Suspend_functor
{
Vfs::Vfs_handle *handle;
Check(Vfs::Vfs_handle *handle) : handle(handle) { }
bool suspend() override {
return !VFS_THREAD_SAFE(handle->fs().notify_read_ready(handle)); }
} check(handle);
while (!VFS_THREAD_SAFE(handle->fs().notify_read_ready(handle)))
Libc::suspend(check);
/*
* If this call fails, the VFS plugin is expected to call the IO
* handler when the notification request can be processed. The
* libc IO handler will then call 'notify_read_ready()' again
* via 'select_notify()'.
*/
VFS_THREAD_SAFE(handle->fs().notify_read_ready(handle));
}
bool read_ready(Libc::File_descriptor *fd)