| //@ run-fail |
| //@ only-windows |
| |
| fn main() { |
| use std::fs; |
| use std::io::prelude::*; |
| use std::os::windows::prelude::*; |
| use std::ptr; |
| use std::sync::Arc; |
| use std::thread; |
| use std::time::Duration; |
| |
| const FILE_FLAG_OVERLAPPED: u32 = 0x40000000; |
| |
| fn create_pipe_server(path: &str) -> fs::File { |
| let mut path0 = path.as_bytes().to_owned(); |
| path0.push(0); |
| extern "system" { |
| fn CreateNamedPipeA( |
| lpName: *const u8, |
| dwOpenMode: u32, |
| dwPipeMode: u32, |
| nMaxInstances: u32, |
| nOutBufferSize: u32, |
| nInBufferSize: u32, |
| nDefaultTimeOut: u32, |
| lpSecurityAttributes: *mut u8, |
| ) -> RawHandle; |
| } |
| |
| unsafe { |
| let h = CreateNamedPipeA(path0.as_ptr(), 3, 0, 1, 0, 0, 0, ptr::null_mut()); |
| assert_ne!(h as isize, -1); |
| fs::File::from_raw_handle(h) |
| } |
| } |
| |
| let path = "\\\\.\\pipe\\repro"; |
| let mut server = create_pipe_server(path); |
| |
| let client = Arc::new( |
| fs::OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).read(true).open(path).unwrap(), |
| ); |
| |
| let spawn_read = |is_first: bool| { |
| thread::spawn({ |
| let f = client.clone(); |
| move || { |
| let mut buf = [0xcc; 1]; |
| let mut f = f.as_ref(); |
| f.read(&mut buf).unwrap(); |
| if is_first { |
| assert_ne!(buf[0], 0xcc); |
| } else { |
| let b = buf[0]; // capture buf[0] |
| thread::sleep(Duration::from_millis(200)); |
| |
| // Check the buffer hasn't been written to after read. |
| dbg!(buf[0], b); |
| assert_eq!(buf[0], b); |
| } |
| } |
| }) |
| }; |
| |
| let t1 = spawn_read(true); |
| thread::sleep(Duration::from_millis(20)); |
| let t2 = spawn_read(false); |
| thread::sleep(Duration::from_millis(100)); |
| let _ = server.write(b"x"); |
| thread::sleep(Duration::from_millis(100)); |
| let _ = server.write(b"y"); |
| |
| // This is run fail because we need to test for the `abort`. |
| // That failing to run is the success case. |
| if t1.join().is_err() || t2.join().is_err() { |
| return; |
| } else { |
| panic!("success"); |
| } |
| } |