mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 20:19:19 +00:00
Re-introduce support for io_close hook. (#15434)
This commit is contained in:
parent
941e70ab38
commit
eafaff9443
Notes:
git
2025-12-07 11:55:40 +00:00
Merged-By: ioquatix <samuel@codeotaku.com>
22
io.c
22
io.c
@ -5551,18 +5551,9 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
|
||||
fptr->stdio_file = 0;
|
||||
fptr->mode &= ~(FMODE_READABLE|FMODE_WRITABLE);
|
||||
|
||||
// wait for blocking operations to ensure they do not hit EBADF:
|
||||
// Wait for blocking operations to ensure they do not hit EBADF:
|
||||
rb_thread_io_close_wait(fptr);
|
||||
|
||||
// Disable for now.
|
||||
// if (!done && fd >= 0) {
|
||||
// VALUE scheduler = rb_fiber_scheduler_current();
|
||||
// if (scheduler != Qnil) {
|
||||
// VALUE result = rb_fiber_scheduler_io_close(scheduler, fptr->self);
|
||||
// if (!UNDEF_P(result)) done = 1;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!done && stdio_file) {
|
||||
// stdio_file is deallocated anyway even if fclose failed.
|
||||
if ((maygvl_fclose(stdio_file, noraise) < 0) && NIL_P(error)) {
|
||||
@ -5574,6 +5565,15 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
|
||||
done = 1;
|
||||
}
|
||||
|
||||
VALUE scheduler = rb_fiber_scheduler_current();
|
||||
if (!done && fd >= 0 && scheduler != Qnil) {
|
||||
VALUE result = rb_fiber_scheduler_io_close(scheduler, RB_INT2NUM(fd));
|
||||
|
||||
if (!UNDEF_P(result)) {
|
||||
done = RTEST(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (!done && fd >= 0) {
|
||||
// fptr->fd may be closed even if close fails. POSIX doesn't specify it.
|
||||
// We assumes it is closed.
|
||||
@ -5724,10 +5724,12 @@ io_close_fptr(VALUE io)
|
||||
if (!fptr) return 0;
|
||||
if (fptr->fd < 0) return 0;
|
||||
|
||||
// This guards against multiple threads closing the same IO object:
|
||||
if (rb_thread_io_close_interrupt(fptr)) {
|
||||
/* calls close(fptr->fd): */
|
||||
fptr_finalize_flush(fptr, FALSE, KEEPGVL);
|
||||
}
|
||||
|
||||
rb_io_fptr_cleanup(fptr, FALSE);
|
||||
return fptr;
|
||||
}
|
||||
|
||||
@ -255,6 +255,13 @@ class Scheduler
|
||||
end.value
|
||||
end
|
||||
|
||||
# This hook is invoked by `IO#close`. Using a separate IO object
|
||||
# demonstrates that the close operation is asynchronous.
|
||||
def io_close(descriptor)
|
||||
Fiber.blocking{IO.for_fd(descriptor.to_i).close}
|
||||
return true
|
||||
end
|
||||
|
||||
# This hook is invoked by `Kernel#sleep` and `Thread::Mutex#sleep`.
|
||||
def kernel_sleep(duration = nil)
|
||||
# $stderr.puts [__method__, duration, Fiber.current].inspect
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user