mirror of
https://github.com/lloeki/normandy.git
synced 2025-12-06 10:04:39 +01:00
improve waitgroup
This commit is contained in:
parent
aa3bb21334
commit
0bbee7df48
2 changed files with 25 additions and 21 deletions
|
|
@ -5,16 +5,19 @@ class WaitGroup
|
||||||
@waiting = []
|
@waiting = []
|
||||||
end
|
end
|
||||||
|
|
||||||
def add(count)
|
def add(delta)
|
||||||
sync! { @count += count }
|
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
|
end
|
||||||
|
|
||||||
def done
|
def done
|
||||||
sync! do
|
add(-1)
|
||||||
fail 'negative count' if done?
|
|
||||||
@count -= 1
|
|
||||||
wake!
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private def done?
|
private def done?
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ require 'test/unit'
|
||||||
require 'thread'
|
require 'thread'
|
||||||
require 'channel/waitgroup'
|
require 'channel/waitgroup'
|
||||||
|
|
||||||
|
# rubocop:disable Metrics/AbcSize
|
||||||
|
# rubocop:disable Metrics/MethodLength
|
||||||
|
|
||||||
class TestWaitGroup < Test::Unit::TestCase
|
class TestWaitGroup < Test::Unit::TestCase
|
||||||
module Util
|
module Util
|
||||||
def meanwhile(*procs, &blk)
|
def meanwhile(*procs, &blk)
|
||||||
|
|
@ -24,27 +27,25 @@ class TestWaitGroup < Test::Unit::TestCase
|
||||||
def test_waitgroup
|
def test_waitgroup
|
||||||
Time.now.tap do |start|
|
Time.now.tap do |start|
|
||||||
wg = WaitGroup.new
|
wg = WaitGroup.new
|
||||||
wg.add(5)
|
wg.add(2)
|
||||||
ok1 = false
|
ok1 = false
|
||||||
ok2 = false
|
ok2 = false
|
||||||
ok3 = false
|
go -> { sleep 0.3; ok1 = true; wg.done }
|
||||||
ok4 = false
|
go -> { sleep 0.5; ok2 = true; wg.done }
|
||||||
ok5 = false
|
|
||||||
go -> { sleep 0.1; ok1 = true; wg.done }
|
|
||||||
go -> { sleep 0.2; ok2 = true; wg.done }
|
|
||||||
go -> { sleep 0.3; ok3 = true; wg.done }
|
|
||||||
go -> { sleep 0.4; ok4 = true; wg.done }
|
|
||||||
go -> { sleep 0.5; ok5 = true; wg.done }
|
|
||||||
wg.wait
|
wg.wait
|
||||||
duration = Time.now - start
|
duration = Time.now - start
|
||||||
assert_equal(true, duration > 0.45)
|
assert_equal(true, duration > 0.48)
|
||||||
assert_equal(true, duration < 0.70)
|
assert_equal(true, duration < 0.52)
|
||||||
assert_true(ok1)
|
assert_true(ok1)
|
||||||
assert_true(ok2)
|
assert_true(ok2)
|
||||||
assert_true(ok3)
|
|
||||||
assert_true(ok4)
|
|
||||||
assert_true(ok5)
|
|
||||||
assert_raises(RuntimeError) { wg.done }
|
assert_raises(RuntimeError) { wg.done }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_waitgroup_concurrent_add
|
||||||
|
wg = WaitGroup.new
|
||||||
|
go -> { wg.wait }
|
||||||
|
sleep 0.1
|
||||||
|
assert_raises(RuntimeError) { wg.add(1) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue