normandy/lib/channel/waitgroup.rb

41 lines
670 B
Ruby

class WaitGroup
def initialize
@mutex = Mutex.new
@count = 0
@waiting = []
end
def add(delta)
sync! do
@count += delta
fail 'negative WaitGroup counter' if @count < 0
if @waiting.any? && delta > 0 && @count == delta
fail 'misuse: add called concurrently with wait'
end
wake!
end
end
def done
add(-1)
end
private def done?
@count == 0
end
def wait
sync! do
@waiting << Thread.current
@mutex.sleep until done?
end
end
private def wake!
@waiting.each { |t| t.wakeup if t.alive? }
end
private def sync!(&block)
@mutex.synchronize(&block)
end
end