Bug #923
`initialize_copy': wrong argument type #<Class:0x825d23c> (expected Data) (TypeError)
| Status: | Closed | Start date: | ||
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | - | % Done: | 0% |
|
| Category: | core | |||
| Target version: | 1.9.1 Release Candidate | |||
| ruby -v: |
Description
まつもと ゆきひろです In message "Re: [ruby-dev:37572] [Bug:1.9] `initialize_copy': wrong argument type #<Class:0x825d23c> (expected Data) (TypeError)" on Wed, 24 Dec 2008 01:44:13 +0900, Tanaka Akira <akr@fsij.org> writes: | |以下のプログラムで、 | wrong argument type #<Class:0x825d23c> (expected Data) (TypeError) |という奇妙なエラーが出ます。 | |% ./ruby -ve 'f = open("/tmp/x", "w") |1000.times { f.dup.print "a" } |GC.start |' IOのファイナライザを実行する時点ではwrite_lockがすでに解放さ れちゃってるからのようです。とりあえず、 * ファイナライザ実行前にwrite_lockをクリア * io_fflushでwrite_lockを問答無用で参照していたのをやめる という対応で上記のプログラムは動いているように見えます。が、 わざわざwrite_lockをかけていたのをはずしちゃって良いのかとい う判断は私にはつきかねます。 パッチを添付します。 --- 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); @@ -3194,6 +3200,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) {
History
Updated by Nobuyoshi Nakada about 3 years ago
なかだです。 At Wed, 24 Dec 2008 10:08:22 +0900, Yukihiro Matsumoto wrote in [ruby-dev:37573]: > IOのファイナライザを実行する時点ではwrite_lockがすでに解放さ > れちゃってるからのようです。とりあえず、 > > * ファイナライザ実行前にwrite_lockをクリア > * io_fflushでwrite_lockを問答無用で参照していたのをやめる > > という対応で上記のプログラムは動いているように見えます。が、 > わざわざwrite_lockをかけていたのをはずしちゃって良いのかとい > う判断は私にはつきかねます。 ファイナライザ実行時は競合するスレッドはないはずと思われるので、 はずしちゃってよいんではないでしょうか。 -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦
Updated by Yuki Sonoda about 3 years ago
- Category set to core
- Priority changed from Low to Normal
- Target version set to 1.9.1 Release Candidate
Updated by Yukihiro Matsumoto about 3 years ago
まつもと ゆきひろです In message "Re: [ruby-dev:37574] Re: [Bug:1.9] `initialize_copy': wrong argument type #<Class:0x825d23c> (expected Data) (TypeError)" on Wed, 24 Dec 2008 11:31:05 +0900, Nobuyoshi Nakada <nobu@ruby-lang.org> writes: |> わざわざwrite_lockをかけていたのをはずしちゃって良いのかとい |> う判断は私にはつきかねます。 | |ファイナライザ実行時は競合するスレッドはないはずと思われるので、 |はずしちゃってよいんではないでしょうか。 んじゃ、コミットします。ところで、GILがある以上、mutexを使わ なくても単純なフラグでロックが実現できそうな気がするんですが。 そうするといろいろコストが安そうですが、そうでもないんですか ね。
Updated by Nobuyoshi Nakada about 3 years ago
なかだです。 At Wed, 24 Dec 2008 20:30:21 +0900, Yukihiro Matsumoto wrote in [ruby-dev:37581]: > |> わざわざwrite_lockをかけていたのをはずしちゃって良いのかとい > |> う判断は私にはつきかねます。 > | > |ファイナライザ実行時は競合するスレッドはないはずと思われるので、 > |はずしちゃってよいんではないでしょうか。 > > んじゃ、コミットします。ところで、GILがある以上、mutexを使わ > なくても単純なフラグでロックが実現できそうな気がするんですが。 > そうするといろいろコストが安そうですが、そうでもないんですか > ね。 書き込みがblocking regionで並行動作するので、通常のflushでは mutexが必要です。ファイナライザが走る時点では、そういうスレッド は終了しているはず(だから解放できる)だと思います。 -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦
Updated by Yukihiro Matsumoto about 3 years ago
まつもと ゆきひろです In message "Re: [ruby-dev:37589] Re: [Bug:1.9] `initialize_copy': wrong argument type #<Class:0x825d23c> (expected Data) (TypeError)" on Thu, 25 Dec 2008 04:46:23 +0900, Nobuyoshi Nakada <nobu@ruby-lang.org> writes: |書き込みがblocking regionで並行動作するので、通常のflushでは |mutexが必要です。ファイナライザが走る時点では、そういうスレッド |は終了しているはず(だから解放できる)だと思います。 そういえばそういう話でしたね。すっかり忘れてました。