@@ -20,6 +20,162 @@ impl Drop for NonCopyNeedsDrop {
20
20
}
21
21
}
22
22
23
+ // FIXME(connor): Figure out a concise way to test both poison and nonpoison `Mutex` for tests that
24
+ // don't care about poisoning.
25
+ mod nonpoison {
26
+ use std:: sync:: nonpoison:: { MappedMutexGuard , Mutex , MutexGuard } ;
27
+
28
+ use super :: * ;
29
+
30
+ #[ test]
31
+ fn test_needs_drop ( ) {
32
+ assert ! ( !mem:: needs_drop:: <NonCopy >( ) ) ;
33
+ assert ! ( mem:: needs_drop:: <NonCopyNeedsDrop >( ) ) ;
34
+ }
35
+
36
+ #[ test]
37
+ fn smoke ( ) {
38
+ let m = Mutex :: new ( ( ) ) ;
39
+ drop ( m. lock ( ) ) ;
40
+ drop ( m. lock ( ) ) ;
41
+ }
42
+
43
+ #[ test]
44
+ fn lots_and_lots ( ) {
45
+ const J : u32 = 1000 ;
46
+ const K : u32 = 3 ;
47
+
48
+ let m = Arc :: new ( Mutex :: new ( 0 ) ) ;
49
+
50
+ fn inc ( m : & Mutex < u32 > ) {
51
+ for _ in 0 ..J {
52
+ * m. lock ( ) += 1 ;
53
+ }
54
+ }
55
+
56
+ let ( tx, rx) = channel ( ) ;
57
+ for _ in 0 ..K {
58
+ let tx2 = tx. clone ( ) ;
59
+ let m2 = m. clone ( ) ;
60
+ thread:: spawn ( move || {
61
+ inc ( & m2) ;
62
+ tx2. send ( ( ) ) . unwrap ( ) ;
63
+ } ) ;
64
+ let tx2 = tx. clone ( ) ;
65
+ let m2 = m. clone ( ) ;
66
+ thread:: spawn ( move || {
67
+ inc ( & m2) ;
68
+ tx2. send ( ( ) ) . unwrap ( ) ;
69
+ } ) ;
70
+ }
71
+
72
+ drop ( tx) ;
73
+ for _ in 0 ..2 * K {
74
+ rx. recv ( ) . unwrap ( ) ;
75
+ }
76
+ assert_eq ! ( * m. lock( ) , J * K * 2 ) ;
77
+ }
78
+
79
+ #[ test]
80
+ fn try_lock ( ) {
81
+ let m = Mutex :: new ( ( ) ) ;
82
+ * m. try_lock ( ) . unwrap ( ) = ( ) ;
83
+ }
84
+
85
+ #[ test]
86
+ fn test_into_inner ( ) {
87
+ let m = Mutex :: new ( NonCopy ( 10 ) ) ;
88
+ assert_eq ! ( m. into_inner( ) , NonCopy ( 10 ) ) ;
89
+ }
90
+
91
+ #[ test]
92
+ fn test_into_inner_drop ( ) {
93
+ struct Foo ( Arc < AtomicUsize > ) ;
94
+ impl Drop for Foo {
95
+ fn drop ( & mut self ) {
96
+ self . 0 . fetch_add ( 1 , Ordering :: SeqCst ) ;
97
+ }
98
+ }
99
+ let num_drops = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
100
+ let m = Mutex :: new ( Foo ( num_drops. clone ( ) ) ) ;
101
+ assert_eq ! ( num_drops. load( Ordering :: SeqCst ) , 0 ) ;
102
+ {
103
+ let _inner = m. into_inner ( ) ;
104
+ assert_eq ! ( num_drops. load( Ordering :: SeqCst ) , 0 ) ;
105
+ }
106
+ assert_eq ! ( num_drops. load( Ordering :: SeqCst ) , 1 ) ;
107
+ }
108
+
109
+ #[ test]
110
+ fn test_get_mut ( ) {
111
+ let mut m = Mutex :: new ( NonCopy ( 10 ) ) ;
112
+ * m. get_mut ( ) = NonCopy ( 20 ) ;
113
+ assert_eq ! ( m. into_inner( ) , NonCopy ( 20 ) ) ;
114
+ }
115
+
116
+ #[ test]
117
+ fn test_mutex_arc_nested ( ) {
118
+ // Tests nested mutexes and access
119
+ // to underlying data.
120
+ let arc = Arc :: new ( Mutex :: new ( 1 ) ) ;
121
+ let arc2 = Arc :: new ( Mutex :: new ( arc) ) ;
122
+ let ( tx, rx) = channel ( ) ;
123
+ let _t = thread:: spawn ( move || {
124
+ let lock = arc2. lock ( ) ;
125
+ let lock2 = lock. lock ( ) ;
126
+ assert_eq ! ( * lock2, 1 ) ;
127
+ tx. send ( ( ) ) . unwrap ( ) ;
128
+ } ) ;
129
+ rx. recv ( ) . unwrap ( ) ;
130
+ }
131
+
132
+ #[ test]
133
+ fn test_mutex_arc_access_in_unwind ( ) {
134
+ let arc = Arc :: new ( Mutex :: new ( 1 ) ) ;
135
+ let arc2 = arc. clone ( ) ;
136
+ let _ = thread:: spawn ( move || -> ( ) {
137
+ struct Unwinder {
138
+ i : Arc < Mutex < i32 > > ,
139
+ }
140
+ impl Drop for Unwinder {
141
+ fn drop ( & mut self ) {
142
+ * self . i . lock ( ) += 1 ;
143
+ }
144
+ }
145
+ let _u = Unwinder { i : arc2 } ;
146
+ panic ! ( ) ;
147
+ } )
148
+ . join ( ) ;
149
+ let lock = arc. lock ( ) ;
150
+ assert_eq ! ( * lock, 2 ) ;
151
+ }
152
+
153
+ #[ test]
154
+ fn test_mutex_unsized ( ) {
155
+ let mutex: & Mutex < [ i32 ] > = & Mutex :: new ( [ 1 , 2 , 3 ] ) ;
156
+ {
157
+ let b = & mut * mutex. lock ( ) ;
158
+ b[ 0 ] = 4 ;
159
+ b[ 2 ] = 5 ;
160
+ }
161
+ let comp: & [ i32 ] = & [ 4 , 2 , 5 ] ;
162
+ assert_eq ! ( & * mutex. lock( ) , comp) ;
163
+ }
164
+
165
+ #[ test]
166
+ fn test_mapping_mapped_guard ( ) {
167
+ let arr = [ 0 ; 4 ] ;
168
+ let mut lock = Mutex :: new ( arr) ;
169
+ let guard = lock. lock ( ) ;
170
+ let guard = MutexGuard :: map ( guard, |arr| & mut arr[ ..2 ] ) ;
171
+ let mut guard = MappedMutexGuard :: map ( guard, |slice| & mut slice[ 1 ..] ) ;
172
+ assert_eq ! ( guard. len( ) , 1 ) ;
173
+ guard[ 0 ] = 42 ;
174
+ drop ( guard) ;
175
+ assert_eq ! ( * lock. get_mut( ) , [ 0 , 42 , 0 , 0 ] ) ;
176
+ }
177
+ }
178
+
23
179
#[ test]
24
180
fn test_needs_drop ( ) {
25
181
assert ! ( !mem:: needs_drop:: <NonCopy >( ) ) ;
0 commit comments