class Concurrent::Transaction

Constants

ABORTED
AbortError
LeaveError
ReadLogEntry

Public Class Methods

current() click to toggle source
# File lib/concurrent/tvar.rb, line 248
def self.current
  Thread.current[:current_tvar_transaction]
end
current=(transaction) click to toggle source
# File lib/concurrent/tvar.rb, line 252
def self.current=(transaction)
  Thread.current[:current_tvar_transaction] = transaction
end
new() click to toggle source
# File lib/concurrent/tvar.rb, line 172
def initialize
  @read_log  = []
  @write_log = {}
end

Public Instance Methods

abort() click to toggle source
# File lib/concurrent/tvar.rb, line 213
def abort
  unlock
end
commit() click to toggle source
# File lib/concurrent/tvar.rb, line 217
def commit
  return false unless valid?

  @write_log.each_pair do |tvar, value|
    tvar.unsafe_value = value
    tvar.unsafe_increment_version
  end

  unlock

  true
end
read(tvar) click to toggle source
# File lib/concurrent/tvar.rb, line 177
def read(tvar)
  Concurrent::abort_transaction unless valid?

  if @write_log.has_key? tvar
    @write_log[tvar]
  else
    @read_log.push(ReadLogEntry.new(tvar, tvar.unsafe_version))
    tvar.unsafe_value
  end
end
unlock() click to toggle source
# File lib/concurrent/tvar.rb, line 242
def unlock
  @write_log.each_key do |tvar|
    tvar.unsafe_lock.unlock
  end
end
valid?() click to toggle source
# File lib/concurrent/tvar.rb, line 230
def valid?
  @read_log.each do |log_entry|
    unless @write_log.has_key? log_entry.tvar
      if log_entry.tvar.unsafe_version > log_entry.version
        return false
      end
    end
  end

  true
end
write(tvar, value) click to toggle source
# File lib/concurrent/tvar.rb, line 188
def write(tvar, value)
  # Have we already written to this TVar?

  unless @write_log.has_key? tvar
    # Try to lock the TVar

    unless tvar.unsafe_lock.try_lock
      # Someone else is writing to this TVar - abort
      Concurrent::abort_transaction
    end

    # If we previously wrote to it, check the version hasn't changed

    @read_log.each do |log_entry|
      if log_entry.tvar == tvar and tvar.unsafe_version > log_entry.version
        Concurrent::abort_transaction
      end
    end
  end

  # Record the value written

  @write_log[tvar] = value
end