File tree Expand file tree Collapse file tree 3 files changed +39
-0
lines changed
src/tools/miri/tests/pass Expand file tree Collapse file tree 3 files changed +39
-0
lines changed Original file line number Diff line number Diff line change @@ -213,6 +213,7 @@ impl<T> Channel<T> {
213
213
. compare_exchange ( block, new, Ordering :: Release , Ordering :: Relaxed )
214
214
. is_ok ( )
215
215
{
216
+ crate :: thread:: sleep ( core:: time:: Duration :: from_secs ( 2 ) ) ;
216
217
self . head . block . store ( new, Ordering :: Release ) ;
217
218
block = new;
218
219
} else {
Original file line number Diff line number Diff line change @@ -16,6 +16,24 @@ fn smoke() {
16
16
assert_eq ! ( rx. recv( ) . unwrap( ) , 1 ) ;
17
17
}
18
18
19
+ #[ test]
20
+ fn gh_139553 ( ) {
21
+ let ( s1, r) = channel :: < u64 > ( ) ;
22
+ let s2 = s1. clone ( ) ;
23
+ // This thread will sleep for 2000ms at the critical moment
24
+ let t1 = thread:: spawn ( move || assert ! ( s1. send( 42 ) . is_err( ) ) ) ;
25
+ // Give some time for thread 1 to reach the critical state
26
+ thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
27
+ // Send another value which see the tail is not null and will just advance the tail offset to 1
28
+ // and write the value.
29
+ s2. send ( 42 ) . unwrap ( ) ;
30
+ // Now drop the receiver which will attempt to drop a message by reading it since head != tail
31
+ // but head is still a null pointer because the thread t1 is still preempted leading to a
32
+ // segfault.
33
+ drop ( r) ;
34
+ t1. join ( ) . unwrap ( ) ;
35
+ }
36
+
19
37
#[ test]
20
38
fn drop_full ( ) {
21
39
let ( tx, _rx) = channel :: < Box < isize > > ( ) ;
Original file line number Diff line number Diff line change
1
+ use std:: sync:: mpsc:: channel;
2
+ use std:: thread;
3
+ use std:: time:: Duration ;
4
+
5
+ pub fn main ( ) {
6
+ let ( s1, r) = channel :: < u64 > ( ) ;
7
+ let s2 = s1. clone ( ) ;
8
+ // This thread will sleep for 2000ms at the critical moment
9
+ let t1 = thread:: spawn ( move || assert ! ( s1. send( 42 ) . is_err( ) ) ) ;
10
+ // Give some time for thread 1 to reach the critical state
11
+ thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
12
+ // Send another value which see the tail is not null and will just advance the tail offset to 1
13
+ // and write the value.
14
+ s2. send ( 42 ) . unwrap ( ) ;
15
+ // Now drop the receiver which will attempt to drop a message by reading it since head != tail
16
+ // but head is still a null pointer because the thread t1 is still preempted leading to a
17
+ // segfault.
18
+ drop ( r) ;
19
+ t1. join ( ) . unwrap ( ) ;
20
+ }
You can’t perform that action at this time.
0 commit comments