named_pipe icon indicating copy to clipboard operation
named_pipe copied to clipboard

Unreachable code when trying to get ReadHandle using .wait()

Open DarkKnightAnk opened this issue 3 years ago • 2 comments

When trying to get read handle on a pipe server, the code reaches unreachable code during drop. Following can gets the error consistently

fn main() {
    let pipe_name = r"\\.\pipe\testpipe".to_string();
    let mut connecting_server = 
            PipeOptions::new(pipe_name.clone()).open_mode(OpenMode::Read).single().unwrap();
    let mut pipe_server = connecting_server.wait().unwrap();
    pipe_server.set_read_timeout(Some(Duration::from_millis(50000)));
    let response: Vec<u8> = [0].repeat(PIPE_BUFFER_SIZE);
    let handle = pipe_server.read_async_owned(response);
    let read_result = read_handle.wait(); // This line causes the crash on the drop
}

On looking at the source, in ReadHandle:: wait, I see that the handle is taken from the option, so it should leave the item with None, but during the drop for ReadHandle, it is trying to access self.get_read_timeout(), which reaches unreachable code since both io, and io_ref objects are None due to the take option here

pub fn wait(mut self) -> io::Result<(usize, Option<(T, Vec<u8>)>)> {
       let result = self.wait_impl();
       let output = {
           let io = self.io.take(); // This line
           let bytes_read = self.bytes_read;
           let buffer = self.buffer.take();
           if let Some(buf) = buffer {
               if let Some(io) = io {
                   Ok((bytes_read as usize, Some((io, buf))))
               } else {
                   unreachable!()
               }
           } else {
               Ok((bytes_read as usize, None))
           }
       };
       match result {
           Ok(_) => output,
           Err(err) => {
               if err.raw_os_error() == Some(ERROR_BROKEN_PIPE as i32) {
                   output
               } else {
                   Err(err)
               }
           }
       }
   }

Is there a purpose of the timeout value at the drop time? I believe pending should be enough to determine whether the operation is to be cancelled correct? If the timeout value is set to 0, that would mean that the handle returned immediately.

DarkKnightAnk avatar Mar 24 '22 18:03 DarkKnightAnk

Hi. Sorry. There are few major issues that requires consideration, but I have no capacity to support this library it at the moment. Please consider switching to the tokio implementation: https://docs.rs/tokio/latest/tokio/net/windows/named_pipe/index.html

blackbeam avatar Mar 24 '22 19:03 blackbeam

Thanks for the quick response! Will take a look at the tokio implementation!

DarkKnightAnk avatar Mar 24 '22 23:03 DarkKnightAnk