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

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

Open
DarkKnightAnk opened this issue Mar 24, 2022 · 2 comments
Open

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

DarkKnightAnk opened this issue Mar 24, 2022 · 2 comments

Comments

@DarkKnightAnk
Copy link

DarkKnightAnk commented Mar 24, 2022

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.

@blackbeam
Copy link
Owner

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

@DarkKnightAnk
Copy link
Author

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants