From: Masaki Matsushita Date: 2011-03-07T09:47:39+09:00 Subject: [ruby-dev:43323] [Ruby 1.9 - Bug #4474] 複数のスレッドからトランザクションに入ろうとした場合のPStoreの挙動 Issue #4474 has been updated by Masaki Matsushita. File patch.diff added 僕もパッチを書いてみましたので添付します。 sora_hさんが書いたパッチと異なる点は、トランザクションに入っているスレッドがあるかどうかを格納しているインスタンス変数@transactionを廃して、 Mutexがロックされているかどうかでトランザクションに入っているスレッドがあるかどうかを判定している点です。 また、第2引数thread_safeの真偽に関わらずトランザクション内の処理をMutexで同期しますが、互換性の為、thread_safeが偽である場合にトランザクションを入ろうとすると例外nested transactionが発生するようにしてあります。 test_pstoreもpassします。 いかがでしょうか。 ---------------------------------------- Bug #4474: 複数のスレッドからトランザクションに入ろうとした場合のPStoreの挙動 http://redmine.ruby-lang.org/issues/4474 Author: Masaki Matsushita Status: Open Priority: Normal Assignee: Category: lib Target version: ruby -v: - PStoreは、initializeの第2引数thread_safeが真であればデータベースの読み書きをMutexで同期するようになっています。 しかし、次のコード require 'pstore' require 'thread' pstore = PStore.new("foo", true) q = Queue.new Thread.start do pstore.transaction do pstore[:hoge] = "fuga" q.push(nil) sleep end end q.pop pstore.transaction do p pstore[:hoge] end を実行すると例外が発生します。 /usr/local/lib/ruby/1.9.1/pstore.rb:321:in `transaction': nested transaction (PStore::Error) from pstore.rb:16:in `
' 以下のコードはpstore.rbの319行目以降から抜粋したものです。 319 def transaction(read_only = false, &block) # :yields: pstore 320 value = nil 321 raise PStore::Error, "nested transaction" if @transaction 322 @lock.synchronize do      (中略) 348 end (中略) 352 end Mutexで保護されたセクションに入る前に、別のトランザクションが実行されていないかどうか調べています。 あるスレッドがトランザクションを実行中に別のスレッドがトランザクションに入ろうとすると、ここで例外が発生します。 thread-safeの定義にも依りますが、これはバグではないでしょうか? -- http://redmine.ruby-lang.org