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