summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--io.c68
-rw-r--r--test/fiber/test_io.rb35
-rw-r--r--version.h4
3 files changed, 74 insertions, 33 deletions
diff --git a/io.c b/io.c
index 48592ac51a..bc31c7bffd 100644
--- a/io.c
+++ b/io.c
@@ -1306,71 +1306,77 @@ rb_io_from_fd(int fd)
int
rb_io_wait_readable(int f)
{
- VALUE scheduler = rb_scheduler_current();
- if (scheduler != Qnil) {
- return RTEST(
- rb_scheduler_io_wait_readable(scheduler, rb_io_from_fd(f))
- );
- }
+ VALUE scheduler;
io_fd_check_closed(f);
+
+ scheduler = rb_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_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_scheduler_current();
- if (scheduler != Qnil) {
- return RTEST(
- rb_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
- );
- }
+ VALUE scheduler;
io_fd_check_closed(f);
+
+ scheduler = rb_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_scheduler_io_wait_writable(scheduler, rb_io_from_fd(f))
+ );
+ } else {
+ rb_thread_fd_writable(f);
+ }
+ return TRUE;
default:
- return FALSE;
+ return FALSE;
}
}
diff --git a/test/fiber/test_io.rb b/test/fiber/test_io.rb
index f01cc3af1b..fafda7c310 100644
--- a/test/fiber/test_io.rb
+++ b/test/fiber/test_io.rb
@@ -62,4 +62,39 @@ class TestFiberIO < Test::Unit::TestCase
end
end.each(&:join)
end
+
+ def test_epipe_on_read
+ skip "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ i, o = UNIXSocket.pair
+
+ unless i.nonblock? && o.nonblock?
+ i.close
+ o.close
+ skip "I/O is not non-blocking!"
+ end
+
+ error = nil
+
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ begin
+ i.close
+ o.write(MESSAGE)
+ rescue => error
+ # Saved into error.
+ end
+ end
+ end
+
+ thread.join
+
+ i.close
+ o.close
+
+ assert_kind_of Errno::EPIPE, error
+ end
end
diff --git a/version.h b/version.h
index 413340163f..f4cfe79521 100644
--- a/version.h
+++ b/version.h
@@ -12,11 +12,11 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 2
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 71
+#define RUBY_PATCHLEVEL 72
#define RUBY_RELEASE_YEAR 2021
#define RUBY_RELEASE_MONTH 4
-#define RUBY_RELEASE_DAY 18
+#define RUBY_RELEASE_DAY 24
#include "ruby/version.h"