From 2b41a6ea6b1d893044274a85262acc5ba5a4a51d Mon Sep 17 00:00:00 2001 From: Hiroshi Shirosaki Date: Thu, 21 Sep 2017 19:04:51 +0900 Subject: [PATCH] io.c: fix segfault with closing socket on MinGW Closing without GVL causes another exception while raising exception in another thread. This causes segfault on MinGW. Keep GVL with close when another thread raises. --- io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/io.c b/io.c index 0f6afb7bc4..c8772adb32 100644 --- a/io.c +++ b/io.c @@ -4295,7 +4295,7 @@ static void free_io_buffer(rb_io_buffer_t *buf); static void clear_codeconv(rb_io_t *fptr); static void -fptr_finalize_flush(rb_io_t *fptr, int noraise) +fptr_finalize_flush(rb_io_t *fptr, int noraise, int keepgvl) { VALUE err = Qnil; int fd = fptr->fd; @@ -4343,7 +4343,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise) * We assumes it is closed. */ /**/ - int keepgvl = !(mode & FMODE_WRITABLE); + keepgvl |= !(mode & FMODE_WRITABLE); keepgvl |= noraise; if ((maygvl_close(fd, keepgvl) < 0) && NIL_P(err)) err = noraise ? Qtrue : INT2NUM(errno); @@ -4360,7 +4360,7 @@ fptr_finalize_flush(rb_io_t *fptr, int noraise) static void fptr_finalize(rb_io_t *fptr, int noraise) { - fptr_finalize_flush(fptr, noraise); + fptr_finalize_flush(fptr, noraise, FALSE); free_io_buffer(&fptr->rbuf); free_io_buffer(&fptr->wbuf); clear_codeconv(fptr); @@ -4464,8 +4464,8 @@ io_close_fptr(VALUE io) fd = fptr->fd; busy = rb_notify_fd_close(fd); - fptr_finalize_flush(fptr, FALSE); if (busy) { + fptr_finalize_flush(fptr, FALSE, TRUE); do rb_thread_schedule(); while (rb_notify_fd_close(fd)); } rb_io_fptr_cleanup(fptr, FALSE); -- 2.14.1.windows.1