In Files

  • sync.rb

Sync_m

Constants

EX
RCS_ID
SH
UN

lock mode

Attributes

sync_ex_count[RW]
sync_ex_locker[RW]
sync_mode[RW]
sync_sh_locker[RW]
sync_upgrade_waiting[RW]
sync_waiting[RW]

Public Class Methods

append_features(cl) click to toggle source
 
               # File sync.rb, line 91
def Sync_m.append_features(cl)
  super
  unless cl.instance_of?(Module)
    # do nothing for Modules
    # make aliases and include the proper module.
    define_aliases(cl)
  end
end
            
define_aliases(cl) click to toggle source
 
               # File sync.rb, line 79
def Sync_m.define_aliases(cl)
  cl.module_eval %q{
    alias locked? sync_locked?
    alias shared? sync_shared?
    alias exclusive? sync_exclusive?
    alias lock sync_lock
    alias unlock sync_unlock
    alias try_lock sync_try_lock
    alias synchronize sync_synchronize
  }
end
            
extend_object(obj) click to toggle source
 
               # File sync.rb, line 100
def Sync_m.extend_object(obj)
  super
  obj.sync_extended
end
            
new(*args) click to toggle source
 
               # File sync.rb, line 255
def initialize(*args)
  sync_initialize
  super
end
            

Public Instance Methods

sync_exclusive?() click to toggle source
 
               # File sync.rb, line 127
def sync_exclusive?
  sync_mode == EX
end
            
sync_extended() click to toggle source
 
               # File sync.rb, line 105
def sync_extended
  unless (defined? locked? and
          defined? shared? and
          defined? exclusive? and
          defined? lock and
          defined? unlock and
          defined? try_lock and
          defined? synchronize)
    Sync_m.define_aliases(class<<self;self;end)
  end
  sync_initialize
end
            
sync_lock(m = EX) click to toggle source
 
               # File sync.rb, line 141
def sync_lock(m = EX)
  return unlock if m == UN

  until (Thread.critical = true; sync_try_lock_sub(m))
    if sync_sh_locker[Thread.current]
      sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
      sync_sh_locker.delete(Thread.current)
    else
      sync_waiting.push Thread.current
    end
    Thread.stop
  end
  Thread.critical = false
  self
end
            
sync_locked?() click to toggle source

accessing

 
               # File sync.rb, line 119
def sync_locked?
  sync_mode != UN
end
            
sync_shared?() click to toggle source
 
               # File sync.rb, line 123
def sync_shared?
  sync_mode == SH
end
            
sync_synchronize(mode = EX) click to toggle source
 
               # File sync.rb, line 227
def sync_synchronize(mode = EX)
  begin
    sync_lock(mode)
    yield
  ensure
    sync_unlock
  end
end
            
sync_try_lock(mode = EX) click to toggle source

locking methods.

 
               # File sync.rb, line 132
def sync_try_lock(mode = EX)
  return unlock if mode == UN
  
  Thread.critical = true
  ret = sync_try_lock_sub(mode)
  Thread.critical = false
  ret
end
            
sync_unlock(m = EX) click to toggle source
 
               # File sync.rb, line 157
def sync_unlock(m = EX)
  Thread.critical = true
  if sync_mode == UN
    Thread.critical = false
    Err::UnknownLocker.Fail(Thread.current)
  end
  
  m = sync_mode if m == EX and sync_mode == SH
  
  runnable = false
  case m
  when UN
    Thread.critical = false
    Err::UnknownLocker.Fail(Thread.current)
    
  when EX
    if sync_ex_locker == Thread.current
      if (self.sync_ex_count = sync_ex_count - 1) == 0
        self.sync_ex_locker = nil
        if sync_sh_locker.include?(Thread.current)
          self.sync_mode = SH
        else
          self.sync_mode = UN
        end
        runnable = true
      end
    else
      Err::UnknownLocker.Fail(Thread.current)
    end
    
  when SH
    if (count = sync_sh_locker[Thread.current]).nil?
      Err::UnknownLocker.Fail(Thread.current)
    else
      if (sync_sh_locker[Thread.current] = count - 1) == 0 
        sync_sh_locker.delete(Thread.current)
        if sync_sh_locker.empty? and sync_ex_count == 0
          self.sync_mode = UN
          runnable = true
        end
      end
    end
  end
  
  if runnable
    if sync_upgrade_waiting.size > 0
      for k, v in sync_upgrade_waiting
        sync_sh_locker[k] = v
      end
      wait = sync_upgrade_waiting
      self.sync_upgrade_waiting = []
      Thread.critical = false
      
      for w, v in wait
        w.run
      end
    else
      wait = sync_waiting
      self.sync_waiting = []
      Thread.critical = false
      for w in wait
        w.run
      end
    end
  end
  
  Thread.critical = false
  self
end