v / vlib / sync / select_close_test.v
94 lines · 87 sloc · 1.64 KB · 8e35f4d9848f7ad35d857a187dddbfd2eca5e19d
Raw
1// vtest retry: 3
2module sync
3
4import time
5
6fn do_rec_i64(mut ch Channel) {
7 mut sum := i64(0)
8 for i in 0 .. 300 {
9 if i == 200 {
10 ch.close()
11 }
12 mut a := i64(0)
13 if ch.pop(&a) {
14 sum += a
15 }
16 }
17 assert sum == 200 * (200 - 1) / 2
18}
19
20fn do_send_int(mut ch Channel) {
21 for i in 0 .. 300 {
22 ch.push(&i)
23 }
24 ch.close()
25}
26
27fn do_send_u8(mut ch Channel) {
28 for i in 0 .. 300 {
29 ii := u8(i)
30 ch.push(&ii)
31 }
32 ch.close()
33}
34
35fn do_send_i64(mut ch Channel) {
36 for i in 0 .. 300 {
37 ii := i64(i)
38 ch.push(&ii)
39 }
40 ch.close()
41}
42
43fn test_select() {
44 mut chi := new_channel[int](0)
45 mut chl := new_channel[i64](1)
46 mut chb := new_channel[u8](10)
47 mut recch := new_channel[i64](0)
48 spawn do_rec_i64(mut recch)
49 spawn do_send_int(mut chi)
50 spawn do_send_u8(mut chb)
51 spawn do_send_i64(mut chl)
52 mut channels := [chi, recch, chl, chb]
53 directions := [Direction.pop, .push, .pop, .pop]
54 mut sum := i64(0)
55 mut rl := i64(0)
56 mut ri := int(0)
57 mut rb := u8(0)
58 mut sl := i64(0)
59 mut objs := [voidptr(&ri), &sl, &rl, &rb]
60 for j in 0 .. 1101 {
61 idx := channel_select(mut channels, directions, mut objs, time.infinite)
62 match idx {
63 0 {
64 sum += ri
65 }
66 1 {
67 sl++
68 }
69 2 {
70 sum += rl
71 }
72 3 {
73 sum += rb
74 }
75 -2 {
76 // channel was closed - last item
77 assert j == 1100
78 }
79 else {
80 println('got ${idx} (timeout)')
81 assert false
82 }
83 }
84
85 if j == 1100 {
86 // check also in other direction
87 assert idx == -2
88 }
89 }
90 // Use Gauß' formula for the first 2 contributions
91 // the 3rd contribution is `byte` and must be seen modulo 256
92 expected_sum := 2 * (300 * (300 - 1) / 2) + 256 * (256 - 1) / 2 + 44 * (44 - 1) / 2
93 assert sum == expected_sum
94}
95