diff --git a/ChangeLog b/ChangeLog index 23edef2a39..629309d5f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Thu Dec 25 15:54:00 2008 Yukihiro Matsumoto + + * io.c (io_fflush): flush write buffer without write lock in + finalizers. [ruby-dev:37572] + + * io.c (rb_io_fptr_finalize): clear write lock before finalizing. + Thu Dec 25 15:07:22 2008 Tanaka Akira * io.c (fptr_finalize): close the IO object even if close(2) is failed. diff --git a/io.c b/io.c index 05635d4228..d39180d6b1 100644 --- a/io.c +++ b/io.c @@ -558,7 +558,13 @@ io_fflush(rb_io_t *fptr) retry: if (fptr->wbuf_len == 0) return 0; - r = rb_mutex_synchronize(fptr->write_lock, io_flush_buffer, (VALUE)fptr); + if (fptr->write_lock) { + r = rb_mutex_synchronize(fptr->write_lock, io_flush_buffer, (VALUE)fptr); + } + else { + long l = io_writable_length(fptr, fptr->wbuf_len); + r = rb_write_internal(fptr->fd, fptr->wbuf+fptr->wbuf_off, l); + } /* xxx: Other threads may modify wbuf. * A lock is required, definitely. */ rb_io_check_closed(fptr); @@ -3190,6 +3196,7 @@ rb_io_fptr_finalize(rb_io_t *fptr) { if (!fptr) return 0; fptr->pathv = Qnil; + fptr->write_lock = 0; if (0 <= fptr->fd) rb_io_fptr_cleanup(fptr, Qtrue); if (fptr->rbuf) {