@@ -5551,18 +5551,9 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl)
55515551 fptr -> stdio_file = 0 ;
55525552 fptr -> mode &= ~(FMODE_READABLE |FMODE_WRITABLE );
55535553
5554- // wait for blocking operations to ensure they do not hit EBADF:
5554+ // Wait for blocking operations to ensure they do not hit EBADF:
55555555 rb_thread_io_close_wait (fptr );
55565556
5557- // Disable for now.
5558- // if (!done && fd >= 0) {
5559- // VALUE scheduler = rb_fiber_scheduler_current();
5560- // if (scheduler != Qnil) {
5561- // VALUE result = rb_fiber_scheduler_io_close(scheduler, fptr->self);
5562- // if (!UNDEF_P(result)) done = 1;
5563- // }
5564- // }
5565-
55665557 if (!done && stdio_file ) {
55675558 // stdio_file is deallocated anyway even if fclose failed.
55685559 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)
55745565 done = 1 ;
55755566 }
55765567
5568+ VALUE scheduler = rb_fiber_scheduler_current ();
5569+ if (!done && fd >= 0 && scheduler != Qnil ) {
5570+ VALUE result = rb_fiber_scheduler_io_close (scheduler , RB_INT2NUM (fd ));
5571+
5572+ if (!UNDEF_P (result )) {
5573+ done = RTEST (result );
5574+ }
5575+ }
5576+
55775577 if (!done && fd >= 0 ) {
55785578 // fptr->fd may be closed even if close fails. POSIX doesn't specify it.
55795579 // We assumes it is closed.
@@ -5724,10 +5724,12 @@ io_close_fptr(VALUE io)
57245724 if (!fptr ) return 0 ;
57255725 if (fptr -> fd < 0 ) return 0 ;
57265726
5727+ // This guards against multiple threads closing the same IO object:
57275728 if (rb_thread_io_close_interrupt (fptr )) {
57285729 /* calls close(fptr->fd): */
57295730 fptr_finalize_flush (fptr , FALSE, KEEPGVL );
57305731 }
5732+
57315733 rb_io_fptr_cleanup (fptr , FALSE);
57325734 return fptr ;
57335735}
0 commit comments