@@ -22,6 +22,22 @@ fn main() {
22
22
check_condattr ( ) ;
23
23
}
24
24
25
+ // We want to only use pthread APIs here for easier testing.
26
+ // So we can't use `thread::scope`. That means panics can lead
27
+ // to a failure to join threads which can lead to further issues,
28
+ // so let's turn such unwinding into aborts.
29
+ struct AbortOnDrop ;
30
+ impl AbortOnDrop {
31
+ fn defuse ( self ) {
32
+ mem:: forget ( self ) ;
33
+ }
34
+ }
35
+ impl Drop for AbortOnDrop {
36
+ fn drop ( & mut self ) {
37
+ std:: process:: abort ( ) ;
38
+ }
39
+ }
40
+
25
41
fn test_mutex_libc_init_recursive ( ) {
26
42
unsafe {
27
43
let mut attr: libc:: pthread_mutexattr_t = mem:: zeroed ( ) ;
@@ -122,6 +138,7 @@ impl<T> Clone for SendPtr<T> {
122
138
}
123
139
124
140
fn check_mutex ( ) {
141
+ let bomb = AbortOnDrop ;
125
142
// Specifically *not* using `Arc` to make sure there is no synchronization apart from the mutex.
126
143
unsafe {
127
144
let data = SyncUnsafeCell :: new ( ( libc:: PTHREAD_MUTEX_INITIALIZER , 0 ) ) ;
@@ -148,9 +165,11 @@ fn check_mutex() {
148
165
assert_eq ! ( libc:: pthread_mutex_trylock( mutexptr) , 0 ) ;
149
166
assert_eq ! ( ( * ptr. ptr) . 1 , 3 ) ;
150
167
}
168
+ bomb. defuse ( ) ;
151
169
}
152
170
153
171
fn check_rwlock_write ( ) {
172
+ let bomb = AbortOnDrop ;
154
173
unsafe {
155
174
let data = SyncUnsafeCell :: new ( ( libc:: PTHREAD_RWLOCK_INITIALIZER , 0 ) ) ;
156
175
let ptr = SendPtr { ptr : data. get ( ) } ;
@@ -187,9 +206,11 @@ fn check_rwlock_write() {
187
206
assert_eq ! ( libc:: pthread_rwlock_tryrdlock( rwlockptr) , 0 ) ;
188
207
assert_eq ! ( ( * ptr. ptr) . 1 , 3 ) ;
189
208
}
209
+ bomb. defuse ( ) ;
190
210
}
191
211
192
212
fn check_rwlock_read_no_deadlock ( ) {
213
+ let bomb = AbortOnDrop ;
193
214
unsafe {
194
215
let l1 = SyncUnsafeCell :: new ( libc:: PTHREAD_RWLOCK_INITIALIZER ) ;
195
216
let l1 = SendPtr { ptr : l1. get ( ) } ;
@@ -213,9 +234,11 @@ fn check_rwlock_read_no_deadlock() {
213
234
assert_eq ! ( libc:: pthread_rwlock_rdlock( l2. ptr) , 0 ) ;
214
235
handle. join ( ) . unwrap ( ) ;
215
236
}
237
+ bomb. defuse ( ) ;
216
238
}
217
239
218
240
fn check_cond ( ) {
241
+ let bomb = AbortOnDrop ;
219
242
unsafe {
220
243
let mut cond: MaybeUninit < libc:: pthread_cond_t > = MaybeUninit :: uninit ( ) ;
221
244
assert_eq ! ( libc:: pthread_cond_init( cond. as_mut_ptr( ) , ptr:: null( ) ) , 0 ) ;
@@ -260,6 +283,7 @@ fn check_cond() {
260
283
261
284
t. join ( ) . unwrap ( ) ;
262
285
}
286
+ bomb. defuse ( ) ;
263
287
}
264
288
265
289
fn check_condattr ( ) {
0 commit comments