lib/perobs/Cache.rb in perobs-4.4.0 vs lib/perobs/Cache.rb in perobs-4.5.0
- old
+ new
@@ -163,14 +163,24 @@
# Tell the cache to start a new transaction. If no other transaction is
# active, the write cache is flushed before the transaction is started.
def begin_transaction
if @transaction_stack.empty?
+ if @transaction_thread
+ PEROBS.log.fatal 'transaction_thread must be nil'
+ end
+ @transaction_thread = Thread.current
# The new transaction is the top-level transaction. Flush the write
# buffer to save the current state of all objects.
flush
else
+ # Nested transactions are currently only supported within the same
+ # thread. If we are in another thread, raise TransactionInOtherThread
+ # to pause the calling thread for a bit.
+ if @transaction_thread != Thread.current
+ raise TransactionInOtherThread
+ end
# Save a copy of all objects that were modified during the enclosing
# transaction.
@transaction_stack.last.each do |id|
@transaction_objects[id]._stash(@transaction_stack.length - 1)
end
@@ -190,10 +200,11 @@
when 1
# All transactions completed successfully. Write all modified objects
# into the backend storage.
@transaction_stack.pop.each { |id| @transaction_objects[id]._sync }
@transaction_objects = ::Hash.new
+ @transaction_thread = nil
else
# A nested transaction completed successfully. We add the list of
# modified objects to the list of the enclosing transaction.
transactions = @transaction_stack.pop
# Merge the two lists
@@ -211,10 +222,11 @@
PEROBS.log.fatal 'No ongoing transaction to abort'
end
@transaction_stack.pop.each do |id|
@transaction_objects[id]._restore(@transaction_stack.length)
end
+ @transaction_thread = nil
end
# Clear all cached entries. You must call flush before calling this
# method. Otherwise unwritten objects will be lost.
def reset
@@ -222,9 +234,10 @@
# significant bits of the PEROBS::ObjectBase ID to select the index in
# the read or write cache Arrays.
@reads = ::Array.new(2 ** @bits)
@writes = ::Array.new(2 ** @bits)
@transaction_stack = ::Array.new
+ @transaction_thread = nil
@transaction_objects = ::Hash.new
end
# Don't include the cache buffers in output of other objects that
# reference Cache.