Class: Polyphony::Mutex

Inherits:
Object show all
Defined in:
lib/polyphony/core/sync.rb

Overview

Implements mutex lock for synchronizing access to a shared resource. This class replaces the stock Thread::Mutex class.

Direct Known Subclasses

Monitor

Instance Method Summary collapse

Constructor Details

#initializeMutex

Initializes a new mutex.



10
11
12
13
# File 'lib/polyphony/core/sync.rb', line 10

def initialize
  @store = Queue.new
  @store << :token
end

Instance Method Details

#conditional_reacquireFiber

Conditionally reacquires the mutex. This method is used by condition variables.

Returns:

  • (Fiber)

    current fiber



40
41
42
43
# File 'lib/polyphony/core/sync.rb', line 40

def conditional_reacquire
  @store.shift
  @holding_fiber = Fiber.current
end

#conditional_releasenil

Conditionally releases the mutex. This method is used by condition variables.

Returns:

  • (nil)


31
32
33
34
# File 'lib/polyphony/core/sync.rb', line 31

def conditional_release
  @store << true
  @holding_fiber = nil
end

#lockMutex

Obtains a lock. Raises ThreadError if mutex is locked by the current thread.

Returns:

Raises:

  • (ThreadError)


63
64
65
66
67
68
69
70
# File 'lib/polyphony/core/sync.rb', line 63

def lock
  check_dead_holder
  raise ThreadError if owned?

  @store.shift
  @holding_fiber = Fiber.current
  self
end

#locked?any

Returns a truthy value if the mutex is currently locked.

Returns:

  • (any)

    truthy if fiber is currently locked



55
56
57
# File 'lib/polyphony/core/sync.rb', line 55

def locked?
  @holding_fiber
end

#owned?Fiber?

Returns the fiber currently owning the mutex.

Returns:

  • (Fiber, nil)

    current owner or nil



48
49
50
# File 'lib/polyphony/core/sync.rb', line 48

def owned?
  @holding_fiber == Fiber.current
end

#sleep(timeout = nil) ⇒ Number

Releases the lock and sleeps timeout seconds if it is given and non-nil or forever. Raises ThreadError if mutex wasn’t locked by the current thread.

Parameters:

  • timeout (nil, Number) (defaults to: nil)

    sleep timeout

Returns:

  • (Number)

    slept time in seconds



101
102
103
104
105
106
107
108
109
# File 'lib/polyphony/core/sync.rb', line 101

def sleep(timeout = nil)
  unlock
  t0 = Time.now
  Kernel.sleep(timeout)
  t1 = Time.now
  lock

  return t1 - t0
end

#synchronize(&block) ⇒ any

Locks the mutex, runs the block, then unlocks it.

This method is re-entrant. Recursive calls from the given block will not block.

Returns:

  • (any)

    return value of block



21
22
23
24
25
# File 'lib/polyphony/core/sync.rb', line 21

def synchronize(&block)
  return yield if @holding_fiber == Fiber.current

  synchronize_not_holding(&block)
end

#try_locktrue, false

Attempts to obtain the lock and returns immediately. Returns true if the lock was granted.

Returns:

  • (true, false)


87
88
89
90
91
92
93
# File 'lib/polyphony/core/sync.rb', line 87

def try_lock
  return false if @holding_fiber

  @store.shift
  @holding_fiber = Fiber.current
  true
end

#unlockMutex

Releases the lock. Raises ThreadError if mutex is not locked by the current thread.

Returns:

Raises:

  • (ThreadError)


76
77
78
79
80
81
# File 'lib/polyphony/core/sync.rb', line 76

def unlock
  raise ThreadError if !owned?

  @holding_fiber = nil
  @store << true
end