Skip to content
This repository was archived by the owner on Aug 14, 2023. It is now read-only.
This repository was archived by the owner on Aug 14, 2023. It is now read-only.

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

@DarkKnightAnk

Description

@DarkKnightAnk

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions