mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
Pass errno of readdir to the GVL callback
nogvl_readdir reported a readdir failure by reading errno after
re-acquiring the GVL. Under M:N threads, the thread may be resumed on
another native thread there, and errno is per native thread, so the
exception had a wrong class.
# strace -f -e trace=getdents64 -e inject=getdents64:error=EIO ruby test.rb
p Ractor.new {
4.times { Thread.new { loop { File.exist?("/nonexistent") } } }
sleep 0.1
Dir.children(".") rescue $!.class
}.value
#=> Errno::ENOENT (should be Errno::EIO)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
37561263fc
commit
8d205a7e2f
1 file changed
+6
-5
Notes:
git
2026-10-19 13:17:25 +00:00
@@ -857,11 +857,11 @@ fundamental_encoding_p(rb_encoding *enc)
|
||||
# define READDIR(dir, enc) rb_w32_readdir((dir), (enc))
|
||||
# define READDIR_NOGVL READDIR
|
||||
#else
|
||||
NORETURN(static void *sys_failure(void *function));
|
||||
NORETURN(static void *readdir_failure(void *err));
|
||||
static void *
|
||||
sys_failure(void *function)
|
||||
readdir_failure(void *err)
|
||||
{
|
||||
rb_sys_fail(function);
|
||||
rb_syserr_fail((int)(VALUE)err, "readdir");
|
||||
}
|
||||
|
||||
static void *
|
||||
@@ -869,8 +869,9 @@ nogvl_readdir(void *dir)
|
||||
{
|
||||
rb_errno_set(0);
|
||||
if ((dir = readdir(dir)) == NULL) {
|
||||
if (rb_errno())
|
||||
rb_thread_call_with_gvl(sys_failure, (void *)"readdir");
|
||||
int e = rb_errno();
|
||||
if (e)
|
||||
rb_thread_call_with_gvl(readdir_failure, (void *)(VALUE)e);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user