summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--lib/pstore.rb20
-rw-r--r--test/test_pstore.rb29
3 files changed, 39 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index e831da73e6..b6dcd93cb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Mar 7 22:59:39 2011 Shota Fukumori <sorah@tubusu.net>
+
+ * lib/pstore.rb: Delete variable @transaction and fix #4474. Patch by
+ Masaki Matsushita (Glass_saga).
+
+ * test/test_pstore.rb(test_thread_safe): Add test for #4474.
+
Mon Mar 7 21:31:38 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* process.c (proc_setgroups): replace getgrnam() with getgrnam_r()
diff --git a/lib/pstore.rb b/lib/pstore.rb
index 65cce7b238..3114eb567f 100644
--- a/lib/pstore.rb
+++ b/lib/pstore.rb
@@ -127,21 +127,16 @@ class PStore
if File::exist? file and not File::readable? file
raise PStore::Error, format("file %s not readable", file)
end
- @transaction = false
@filename = file
@abort = false
@ultra_safe = false
@thread_safe = thread_safe
- if @thread_safe
- @lock = Mutex.new
- else
- @lock = DummyMutex.new
- end
+ @lock = Mutex.new
end
# Raises PStore::Error if the calling code is not in a PStore#transaction.
def in_transaction
- raise PStore::Error, "not in transaction" unless @transaction
+ raise PStore::Error, "not in transaction" unless @lock.locked?
end
#
# Raises PStore::Error if the calling code is not in a PStore#transaction or
@@ -318,10 +313,9 @@ class PStore
#
def transaction(read_only = false, &block) # :yields: pstore
value = nil
- raise PStore::Error, "nested transaction" if @transaction
+ raise PStore::Error, "nested transaction" if !@thread_safe && @lock.locked?
@lock.synchronize do
@rdonly = read_only
- @transaction = true
@abort = false
file = open_and_lock_file(@filename, read_only)
if file
@@ -347,8 +341,6 @@ class PStore
end
end
value
- ensure
- @transaction = false
end
private
@@ -357,12 +349,6 @@ class PStore
EMPTY_MARSHAL_DATA = Marshal.dump({})
EMPTY_MARSHAL_CHECKSUM = Digest::MD5.digest(EMPTY_MARSHAL_DATA)
- class DummyMutex
- def synchronize
- yield
- end
- end
-
#
# Open the specified filename (either in read-only mode or in
# read-write mode) and lock it for reading or writing.
diff --git a/test/test_pstore.rb b/test/test_pstore.rb
index e10ce906cb..32d79ea2ba 100644
--- a/test/test_pstore.rb
+++ b/test/test_pstore.rb
@@ -71,4 +71,33 @@ class PStoreTest < Test::Unit::TestCase
end
end
end
+
+ def test_thread_safe
+ assert_raise(PStore::Error) do
+ flag = false
+ Thread.new do
+ @pstore.transaction do
+ @pstore[:foo] = "bar"
+ flag = true
+ sleep 1
+ end
+ end
+ until flag; end
+ @pstore.transaction {}
+ end
+ assert_block do
+ pstore = PStore.new("pstore.tmp2.#{Process.pid}",true)
+ flag = false
+ Thread.new do
+ pstore.transaction do
+ pstore[:foo] = "bar"
+ flag = true
+ sleep 1
+ end
+ end
+ until flag; end
+ pstore.transaction { pstore[:foo] == "bar" }
+ File.unlink("pstore.tmp2.#{Process.pid}") rescue nil
+ end
+ end
end