6 use std::io::prelude::*;
7 use std::os::windows::prelude::*;
11 use std::time::Duration;
13 const FILE_FLAG_OVERLAPPED: u32 = 0x40000000;
15 fn create_pipe_server(path: &str) -> fs::File {
16 let mut path0 = path.as_bytes().to_owned();
27 lpSecurityAttributes: *mut u8,
32 let h = CreateNamedPipeA(path0.as_ptr(), 3, 0, 1, 0, 0, 0, ptr::null_mut());
33 assert_ne!(h as isize, -1);
34 fs::File::from_raw_handle(h)
38 let path = "\\\\.\\pipe\\repro";
39 let mut server = create_pipe_server(path);
41 let client = Arc::new(
42 fs::OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).read(true).open(path).unwrap(),
45 let spawn_read = |is_first: bool| {
47 let f = client.clone();
49 let mut buf = [0xcc; 1];
50 let mut f = f.as_ref();
51 f.read(&mut buf).unwrap();
53 assert_ne!(buf[0], 0xcc);
55 let b = buf[0]; // capture buf[0]
56 thread::sleep(Duration::from_millis(200));
58 // Check the buffer hasn't been written to after read.
60 assert_eq!(buf[0], b);
66 let t1 = spawn_read(true);
67 thread::sleep(Duration::from_millis(20));
68 let t2 = spawn_read(false);
69 thread::sleep(Duration::from_millis(100));
70 let _ = server.write(b"x");
71 thread::sleep(Duration::from_millis(100));
72 let _ = server.write(b"y");
74 // This is run fail because we need to test for the `abort`.
75 // That failing to run is the success case.
76 if t1.join().is_err() || t2.join().is_err() {