aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-10-06 02:52:26 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-10-06 02:52:26 +0000
commit915ae780c37478fea358d6c77513a728e86a10f2 (patch)
tree7776a2822ff87357d287ef8a11609b00f01e66d0
parenta413c84e543528d31190f22ecdf1a5f7363cedc9 (diff)
downloadruby-915ae780c37478fea358d6c77513a728e86a10f2.tar.gz
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29415 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog7
-rw-r--r--io.c12
-rw-r--r--test/ruby/test_io.rb29
3 files changed, 45 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 5f719aaae7..b9207b80fa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Oct 6 11:52:12 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * 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@gmail.com>
* win32/mkexports.rb: revert r29320 and r29402.
diff --git a/io.c b/io.c
index 2a5a6452f7..c368ecb842 100644
--- a/io.c
+++ b/io.c
@@ -3459,7 +3459,7 @@ fptr_finalize(rb_io_t *fptr, int noraise)
{
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 @@ fptr_finalize(rb_io_t *fptr, int noraise)
}
}
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;
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 1cfcba181a..0d89b58b59 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -1625,4 +1625,33 @@ End
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