Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows try_clone returns incorrect trait #22

Closed
dhylands opened this issue Apr 23, 2020 · 1 comment
Closed

Windows try_clone returns incorrect trait #22

dhylands opened this issue Apr 23, 2020 · 1 comment

Comments

@dhylands
Copy link

If I call mio_serial::from_path I get back an instance of the mio_serial::Serial object and calling read/write calls the read/write traits implemented in the mio_serial's windows.rs file.

If I then call try_clone on that instance, it returns self.inner.try_clone which returns an instance of serialport's windows::COMPort and calling read/write on that calls the read/write from serialport rather than the read/write from mio_serial (verified by adding some println's.

This in turn causes a parameter error, since the mio_serial instance calls CreateFileW with the FILE_FLAG_OVERLAPPED flag, which in turns means that ReadFile/WriteFile need to be called with a non-NULL lpOverlapped parameter.

Here's my sample program which reproduces the problem. I was using a USB FTDI adapter with Tx jumpered to Rx so it should receive back what it sends.

use std::io::Read;
use std::io::Write;
use mio_serial::{SerialPort, SerialPortSettings};

fn main() {
  let settings = SerialPortSettings::default();
  if let Ok(mut rx_port) = mio_serial::Serial::from_path("COM6", &settings) {
    let mut tx_port = rx_port.try_clone().unwrap();
    let tx_result = tx_port.write("This is a test".as_bytes());
    println!("tx_result: {:?}", tx_result);
    
    let mut buf: [u8; 14] = [0; 14];
    let rx_result = rx_port.read(&mut buf);
    println!("rx_result: {:?}", rx_result);
  }
}

running this with a println! inside serialport/mio-serial's read/write methods yields this output:

serialport: write: [84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 116, 101, 115, 116] called handle = 0x94
tx_result: Err(Os { code: 87, kind: Other, message: "The parameter is incorrect." })
mio-serial: read called
rx_result: Err(Custom { kind: WouldBlock, error: "would block" })

So we can see that the serialport write function is being called rather than the mio-serial's write and we also get the Invalid parameter because serialport's write passes in NULL for lpOverlapped.

@berkowski
Copy link
Owner

Took a stab at this with a574c5f. Certainly more correct than before but not sure if it fixes the issue. Closing for now but re-open if needed

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

No branches or pull requests

2 participants