ruby-changes:17410
From: nobu <ko1@a...>
Date: Wed, 6 Oct 2010 11:52:37 +0900 (JST)
Subject: [ruby-changes:17410] Ruby:r29415 (trunk): * io.c (fptr_finalize): write_mutex might have been destroyed
nobu 2010-10-06 11:52:26 +0900 (Wed, 06 Oct 2010) New Revision: 29415 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29415 Log: * io.c (fptr_finalize): write_mutex might have been destroyed already in finalization phase, as the order of finalizers is not guaranteed. rb_mutex_t should be used in place of Mutex object in the future. Modified files: trunk/ChangeLog trunk/io.c trunk/test/ruby/test_io.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 29414) +++ ChangeLog (revision 29415) @@ -1,3 +1,10 @@ +Wed Oct 6 11:52:12 2010 Nobuyoshi Nakada <nobu@r...> + + * io.c (fptr_finalize): write_mutex might have been destroyed + already in finalization phase, as the order of finalizers is not + guaranteed. rb_mutex_t should be used in place of Mutex object + in the future. + Tue Oct 5 22:17:02 2010 wanabe <s.wanabe@g...> * win32/mkexports.rb: revert r29320 and r29402. Index: io.c =================================================================== --- io.c (revision 29414) +++ io.c (revision 29415) @@ -3459,7 +3459,7 @@ { VALUE err = Qnil; if (fptr->writeconv) { - if (fptr->write_lock) { + if (fptr->write_lock && !noraise) { struct finish_writeconv_arg arg; arg.fptr = fptr; arg.noalloc = noraise; @@ -3470,8 +3470,14 @@ } } if (fptr->wbuf_len) { - if (io_fflush(fptr) < 0 && NIL_P(err)) - err = noraise ? Qtrue : INT2NUM(errno); + if (noraise) { + if ((int)io_flush_buffer_sync(fptr) < 0 && NIL_P(err)) + err = Qtrue; + } + else { + if (io_fflush(fptr) < 0 && NIL_P(err)) + err = INT2NUM(errno); + } } if (IS_PREP_STDIO(fptr) || fptr->fd <= 2) { goto skip_fd_close; Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 29414) +++ test/ruby/test_io.rb (revision 29415) @@ -1625,4 +1625,33 @@ end end.each {|th| th.join} end + + def test_flush_in_finalizer1 + require 'tempfile' + bug3910 = '[ruby-dev:42341]' + path = Tempfile.new("bug3910").path + fds = [] + assert_nothing_raised(TypeError, bug3910) do + 500.times { + f = File.open(path, "w") + fds << f.fileno + f.print "hoge" + } + end + ensure + fds.each {|fd| IO.for_fd(fd).close rescue next} + end + + def test_flush_in_finalizer2 + require 'tempfile' + bug3910 = '[ruby-dev:42341]' + path = Tempfile.new("bug3910").path + 1.times do + io = open(path,"w") + io.print "hoge" + end + assert_nothing_raised(TypeError, bug3910) do + GC.start + end + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/