mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Check errno before invoking scheduler in rb_io_wait_readable/writable
.
See <https://bugs.ruby-lang.org/issues/17527> for more details.
This commit is contained in:
parent
611e711085
commit
a9c5c2d614
Notes:
git
2021-03-30 19:17:26 +09:00
1 changed files with 37 additions and 33 deletions
70
io.c
70
io.c
|
@ -1305,71 +1305,75 @@ rb_io_from_fd(int fd)
|
|||
int
|
||||
rb_io_wait_readable(int f)
|
||||
{
|
||||
VALUE scheduler = rb_fiber_scheduler_current();
|
||||
if (scheduler != Qnil) {
|
||||
return RTEST(
|
||||
rb_fiber_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
|
||||
);
|
||||
}
|
||||
|
||||
io_fd_check_closed(f);
|
||||
|
||||
VALUE scheduler = rb_fiber_scheduler_current();
|
||||
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
#if defined(ERESTART)
|
||||
case ERESTART:
|
||||
#endif
|
||||
rb_thread_check_ints();
|
||||
return TRUE;
|
||||
rb_thread_check_ints();
|
||||
return TRUE;
|
||||
|
||||
case EAGAIN:
|
||||
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
rb_thread_wait_fd(f);
|
||||
return TRUE;
|
||||
if (scheduler != Qnil) {
|
||||
return RTEST(
|
||||
rb_fiber_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
|
||||
);
|
||||
} else {
|
||||
rb_thread_wait_fd(f);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rb_io_wait_writable(int f)
|
||||
{
|
||||
VALUE scheduler = rb_fiber_scheduler_current();
|
||||
if (scheduler != Qnil) {
|
||||
return RTEST(
|
||||
rb_fiber_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
|
||||
);
|
||||
}
|
||||
|
||||
io_fd_check_closed(f);
|
||||
|
||||
VALUE scheduler = rb_fiber_scheduler_current();
|
||||
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
#if defined(ERESTART)
|
||||
case ERESTART:
|
||||
#endif
|
||||
/*
|
||||
* In old Linux, several special files under /proc and /sys don't handle
|
||||
* select properly. Thus we need avoid to call if don't use O_NONBLOCK.
|
||||
* Otherwise, we face nasty hang up. Sigh.
|
||||
* e.g. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
|
||||
* http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
|
||||
* In EINTR case, we only need to call RUBY_VM_CHECK_INTS_BLOCKING().
|
||||
* Then rb_thread_check_ints() is enough.
|
||||
*/
|
||||
rb_thread_check_ints();
|
||||
return TRUE;
|
||||
/*
|
||||
* In old Linux, several special files under /proc and /sys don't handle
|
||||
* select properly. Thus we need avoid to call if don't use O_NONBLOCK.
|
||||
* Otherwise, we face nasty hang up. Sigh.
|
||||
* e.g. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
|
||||
* http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=31b07093c44a7a442394d44423e21d783f5523b8
|
||||
* In EINTR case, we only need to call RUBY_VM_CHECK_INTS_BLOCKING().
|
||||
* Then rb_thread_check_ints() is enough.
|
||||
*/
|
||||
rb_thread_check_ints();
|
||||
return TRUE;
|
||||
|
||||
case EAGAIN:
|
||||
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
rb_thread_fd_writable(f);
|
||||
return TRUE;
|
||||
if (scheduler != Qnil) {
|
||||
return RTEST(
|
||||
rb_fiber_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
|
||||
);
|
||||
} else {
|
||||
rb_thread_fd_writable(f);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue