v / vlib / sync / rwmutex_test.v
74 lines · 62 sloc · 1.75 KB · da3112e5453b553ca230d47590e0d3ed6be6478d
Raw
1import sync
2import time
3
4struct Counter {
5pub mut:
6 i int
7}
8
9fn write_10000(mut co Counter, mut mx sync.RwMutex) {
10 mx.lock()
11 co.i = 10000
12 mx.unlock()
13}
14
15fn test_rwmutex() {
16 mut co := &Counter{10086}
17 mut mx := sync.new_rwmutex()
18 mx.lock()
19 co.i = 888
20 th1 := spawn write_10000(mut co, mut mx)
21 mx.unlock() // after mx unlock, thread write_10000 can continue
22 th1.wait()
23 assert co.i == 10000
24
25 mx.rlock()
26 th2 := spawn write_10000(mut co, mut mx) // write_10000 will be blocked
27 co.i = 999 // for demo purpose, don't modify data in rlock!
28 time.sleep(1 * time.millisecond)
29 assert co.i == 999
30 mx.runlock() // after rlock released, write_10000 can continue
31 th2.wait()
32 assert co.i == 10000
33 mx.destroy()
34}
35
36fn test_try_lock_rwmutex() {
37 // In Windows, try_lock only avalible after Windows 7
38 $if windows {
39 $if !windows_7 ? {
40 return
41 }
42 }
43 mut mx := sync.new_rwmutex()
44
45 // try_rlock will always fail when mx locked
46 mx.lock()
47 try_fail_reading1 := mx.try_rlock()
48 try_fail_writing1 := mx.try_wlock()
49 assert try_fail_reading1 == false
50 assert try_fail_writing1 == false
51
52 mx.unlock()
53
54 // try_rlock will always succeed when mx unlocked,
55 // multiple try_rlock can apply to the same mx
56 try_success_reading2 := mx.try_rlock()
57 try_success_reading3 := mx.try_rlock()
58 assert try_success_reading2 == true
59 assert try_success_reading3 == true
60
61 // if mx is rlocked, then the try_wlock will fail
62 try_fail_writing2 := mx.try_wlock()
63 assert try_fail_writing2 == false
64
65 mx.runlock()
66 mx.runlock() // you must release rlock multiple times, as it was rlocked multiple times
67
68 // after mx release all rlock, try_wlock will succeed
69 try_success_writing3 := mx.try_wlock()
70 assert try_success_writing3 == true
71
72 mx.unlock() // you must unlock it, after try_wlock success
73 mx.destroy()
74}
75