/usr/lib/ruby/vendor_ruby/em-synchrony/thread.rb is in ruby-em-synchrony 1.0.5-2ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | module EventMachine
module Synchrony
module Thread
# Fiber-aware drop-in replacements for thread objects
class Mutex
def initialize
@waiters = []
@slept = {}
end
def lock
current = Fiber.current
raise FiberError if @waiters.include?(current)
@waiters << current
Fiber.yield unless @waiters.first == current
true
end
def locked?
!@waiters.empty?
end
def _wakeup(fiber)
fiber.resume if @slept.delete(fiber)
end
def sleep(timeout = nil)
unlock
beg = Time.now
current = Fiber.current
@slept[current] = true
if timeout
timer = EM.add_timer(timeout) do
_wakeup(current)
end
Fiber.yield
EM.cancel_timer timer # if we resumes not via timer
else
Fiber.yield
end
@slept.delete current
yield if block_given?
lock
Time.now - beg
end
def try_lock
lock unless locked?
end
def unlock
raise FiberError unless @waiters.first == Fiber.current
@waiters.shift
unless @waiters.empty?
EM.next_tick{ @waiters.first.resume }
end
self
end
def synchronize
lock
yield
ensure
unlock
end
end
class ConditionVariable
#
# Creates a new ConditionVariable
#
def initialize
@waiters = []
end
#
# Releases the lock held in +mutex+ and waits; reacquires the lock on wakeup.
#
# If +timeout+ is given, this method returns after +timeout+ seconds passed,
# even if no other thread doesn't signal.
#
def wait(mutex, timeout=nil)
current = Fiber.current
pair = [mutex, current]
@waiters << pair
mutex.sleep timeout do
@waiters.delete pair
end
self
end
def _wakeup(mutex, fiber)
if alive = fiber.alive?
EM.next_tick {
mutex._wakeup(fiber)
}
end
alive
end
#
# Wakes up the first thread in line waiting for this lock.
#
def signal
while (pair = @waiters.shift)
break if _wakeup(*pair)
end
self
end
#
# Wakes up all threads waiting for this lock.
#
def broadcast
@waiters.each do |mutex, fiber|
_wakeup(mutex, fiber)
end
@waiters.clear
self
end
end
end
end
end
|