In Files

  • sync.rb

Synchronizer_m

A module that provides a two-phase lock with a counter.

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
  # do nothing for Modules
  # make aliases for Classes.
  define_aliases(cl) unless cl.instance_of?(Module)
  self
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 99
def Sync_m.extend_object(obj)
  super
  obj.sync_extend
end
            
new(*args) click to toggle source
 
               # File sync.rb, line 259
def initialize(*args)
  super
  sync_initialize
end
            

Public Instance Methods

sync_exclusive?() click to toggle source
 
               # File sync.rb, line 126
def sync_exclusive?
  sync_mode == EX
end
            
sync_extend() click to toggle source
 
               # File sync.rb, line 104
def sync_extend
  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(singleton_class)
  end
  sync_initialize
end
            
sync_inspect() click to toggle source
 
               # File sync.rb, line 241
def sync_inspect
  sync_iv = instance_variables.select{|iv| /^@sync_/ =~ iv.id2name}.collect{|iv| iv.id2name + '=' + instance_eval(iv.id2name).inspect}.join(",")
  print "<#{self.class}.extend Sync_m: #{inspect}, <Sync_m: #{sync_iv}>"
end
            
sync_lock(m = EX) click to toggle source
 
               # File sync.rb, line 138
def sync_lock(m = EX)
  return unlock if m == UN

  while true
    @sync_mutex.synchronize do
      if sync_try_lock_sub(m)
        return self
      else
        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
        @sync_mutex.sleep
      end
    end
  end
  self
end
            
sync_locked?() click to toggle source

accessing

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

locking methods.

 
               # File sync.rb, line 131
def sync_try_lock(mode = EX)
  return unlock if mode == UN
  @sync_mutex.synchronize do
    sync_try_lock_sub(mode)
  end
end
            
sync_unlock(m = EX) click to toggle source
 
               # File sync.rb, line 159
def sync_unlock(m = EX)
  wakeup_threads = []
  @sync_mutex.synchronize do
    if sync_mode == UN
      Err::UnknownLocker.Fail(Thread.current)
    end

    m = sync_mode if m == EX and sync_mode == SH

    runnable = false
    case m
    when UN
      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
        th, count = sync_upgrade_waiting.shift
        sync_sh_locker[th] = count
        th.wakeup
        wakeup_threads.push th
      else
        wait = sync_waiting
        self.sync_waiting = []
        for th in wait
          th.wakeup
          wakeup_threads.push th
        end
      end
    end
  end
  for th in wakeup_threads
    th.run
  end
  self
end
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus