v / vlib / sync / waitgroup_test.v
95 lines · 82 sloc · 1.59 KB · 5c303f226bf8492ccb62e8586cfa3afd087d085a
Raw
1// vtest retry: 3
2// vtest flaky: true
3module sync
4
5import time
6import sync.stdatomic
7
8fn issue_6870_worker(mut wg WaitGroup, ready chan bool, release chan bool) {
9 ready <- true
10 _ = <-release
11 wg.add(1)
12 wg.done()
13 wg.done()
14}
15
16fn test_waitgroup_reuse() {
17 mut wg := new_waitgroup()
18
19 wg.add(1)
20 wg.done()
21
22 wg.add(1)
23 mut executed := false
24 spawn fn (mut wg WaitGroup, executed voidptr) {
25 defer {
26 wg.done()
27 }
28 unsafe {
29 *(&bool(executed)) = true
30 }
31 time.sleep(100 * time.millisecond)
32 }(mut wg, voidptr(&executed))
33
34 wg.wait()
35 assert executed
36}
37
38fn test_waitgroup_no_use() {
39 done := chan bool{cap: 1}
40 watchdog := spawn fn (done chan bool) {
41 select {
42 _ := <-done {}
43 10 * time.second {
44 panic('test_waitgroup_no_use did not complete in time')
45 }
46 }
47 }(done)
48
49 mut wg := new_waitgroup()
50 wg.wait()
51 done <- true
52 watchdog.wait()
53}
54
55fn test_waitgroup_go() {
56 mut counter := stdatomic.new_atomic(0)
57 mut wg := new_waitgroup()
58 for i in 0 .. 10 {
59 wg.go(fn [mut counter] () {
60 counter.add(1)
61 })
62 }
63 wg.wait()
64 assert counter.load() == 10
65}
66
67fn test_waitgroup_add_while_waiting() {
68 for _ in 0 .. 50 {
69 mut wg := new_waitgroup()
70 ready := chan bool{cap: 1}
71 release := chan bool{cap: 1}
72 wait_done := chan bool{cap: 8}
73 wg.add(1)
74
75 spawn issue_6870_worker(mut wg, ready, release)
76 _ = <-ready
77
78 for _ in 0 .. 8 {
79 spawn fn [mut wg, wait_done] () {
80 wg.wait()
81 wait_done <- true
82 }()
83 }
84 release <- true
85
86 for _ in 0 .. 8 {
87 select {
88 _ := <-wait_done {}
89 2 * time.second {
90 assert false, 'wait() missed a wakeup while work added more tasks'
91 }
92 }
93 }
94 }
95}
96