summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2025-01-25 14:39:22 +0900
committernagachika <nagachika@ruby-lang.org>2025-01-25 14:39:22 +0900
commit97243cc9c76b9cc2803cfd1c01165ab5bd432450 (patch)
treea4a4b346b513afe63d20e0e9e2fb5bf37382a617
parentf9adaab928dff8dd7ecd4c560c288300a3c74880 (diff)
merge revision(s) 04ec07794657cd2444ecb001a522b9df2db1b90a: [Backport #21038]
Preserve `errno` in `rb_fiber_scheduler_unblock`. (#12576) [Bug #21038] Co-authored-by: Julian Scheid <julians37@gmail.com>
-rw-r--r--scheduler.c10
-rw-r--r--version.h2
2 files changed, 10 insertions, 2 deletions
diff --git a/scheduler.c b/scheduler.c
index a56549c7d7..4be18e1799 100644
--- a/scheduler.c
+++ b/scheduler.c
@@ -403,7 +403,15 @@ rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
{
VM_ASSERT(rb_obj_is_fiber(fiber));
- return rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
+ // `rb_fiber_scheduler_unblock` can be called from points where `errno` is expected to be preserved. Therefore, we should save and restore it. For example `io_binwrite` calls `rb_fiber_scheduler_unblock` and if `errno` is reset to 0 by user code, it will break the error handling in `io_write`.
+ // If we explicitly preserve `errno` in `io_binwrite` and other similar functions (e.g. by returning it), this code is no longer needed. I hope in the future we will be able to remove it.
+ int saved_errno = errno;
+
+ VALUE result = rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
+
+ errno = saved_errno;
+
+ return result;
}
/*
diff --git a/version.h b/version.h
index 2ee029f8e9..481a9950f7 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 6
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 250
+#define RUBY_PATCHLEVEL 251
#include "ruby/version.h"
#include "ruby/internal/abi.h"