From 1bc266adebf76e28f579ca5dfc2108f5760afd9a Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 24 Dec 2018 21:53:52 +0100 Subject: [PATCH] Use `Option` for timeouts. --- .travis.yml | 2 +- serial-core/README.md | 6 ++--- serial-core/src/lib.rs | 12 +++++----- serial-unix/src/poll.rs | 45 ++++++++++++++++++++++------------- serial-unix/src/tty.rs | 8 +++---- serial-windows/src/com.rs | 30 +++++++++++++---------- serial/README.md | 2 +- serial/examples/probe_pins.rs | 2 +- serial/examples/read_write.rs | 2 +- 9 files changed, 64 insertions(+), 45 deletions(-) diff --git a/.travis.yml b/.travis.yml index 663f25e..fe9d8a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ os: - linux - osx rust: - - 1.16.0 + - 1.19.0 - stable - beta - nightly diff --git a/serial-core/README.md b/serial-core/README.md index 71a0688..9a5e333 100644 --- a/serial-core/README.md +++ b/serial-core/README.md @@ -52,7 +52,7 @@ fn probe(port: &mut P) -> io::Result<()> { })); // I/O - try!(port.set_timeout(Duration::from_millis(100))); + try!(port.set_timeout(Some(Duration::from_millis(100)))); try!(port.write(&buf[..])); try!(port.read(&mut buf[..])); @@ -174,8 +174,8 @@ impl serial::SerialDevice for CustomSerialPort { fn read_settings(&self) -> serial::Result { ... } fn write_settings(&mut self, settings: &Self::Settings) -> serial::Result<()> { ... } - fn timeout(&self) -> Duration { ... } - fn set_timeout(&mut self, timeout: Duration) -> serial::Result<()> { ... } + fn timeout(&self) -> Option { ... } + fn set_timeout(&mut self, timeout: Option) -> serial::Result<()> { ... } fn set_rts(&mut self, level: bool) -> serial::Result<()> { ... } fn set_dtr(&mut self, level: bool) -> serial::Result<()> { ... } diff --git a/serial-core/src/lib.rs b/serial-core/src/lib.rs index 8d26249..08d3ee5 100644 --- a/serial-core/src/lib.rs +++ b/serial-core/src/lib.rs @@ -341,10 +341,10 @@ pub trait SerialDevice: io::Read + io::Write { fn write_settings(&mut self, settings: &Self::Settings) -> ::Result<()>; /// Returns the current timeout. - fn timeout(&self) -> Duration; + fn timeout(&self) -> Option; /// Sets the timeout for future I/O operations. - fn set_timeout(&mut self, timeout: Duration) -> ::Result<()>; + fn set_timeout(&mut self, timeout: Option) -> ::Result<()>; /// Sets the state of the RTS (Request To Send) control signal. /// @@ -437,10 +437,10 @@ pub trait SerialDevice: io::Read + io::Write { /// The serial port will be closed when the value is dropped. pub trait SerialPort: io::Read + io::Write { /// Returns the current timeout. - fn timeout(&self) -> Duration; + fn timeout(&self) -> Option; /// Sets the timeout for future I/O operations. - fn set_timeout(&mut self, timeout: Duration) -> ::Result<()>; + fn set_timeout(&mut self, timeout: Option) -> ::Result<()>; /// Configures a serial port device. /// @@ -576,11 +576,11 @@ pub trait SerialPort: io::Read + io::Write { impl SerialPort for T where T: SerialDevice { - fn timeout(&self) -> Duration { + fn timeout(&self) -> Option { T::timeout(self) } - fn set_timeout(&mut self, timeout: Duration) -> ::Result<()> { + fn set_timeout(&mut self, timeout: Option) -> ::Result<()> { T::set_timeout(self, timeout) } diff --git a/serial-unix/src/poll.rs b/serial-unix/src/poll.rs index 8de2838..8343639 100644 --- a/serial-unix/src/poll.rs +++ b/serial-unix/src/poll.rs @@ -29,15 +29,15 @@ const POLLERR: c_short = 0x0008; const POLLHUP: c_short = 0x0010; const POLLNVAL: c_short = 0x0020; -pub fn wait_read_fd(fd: c_int, timeout: Duration) -> io::Result<()> { +pub fn wait_read_fd(fd: c_int, timeout: Option) -> io::Result<()> { wait_fd(fd, POLLIN, timeout) } -pub fn wait_write_fd(fd: c_int, timeout: Duration) -> io::Result<()> { +pub fn wait_write_fd(fd: c_int, timeout: Option) -> io::Result<()> { wait_fd(fd, POLLOUT, timeout) } -fn wait_fd(fd: c_int, events: c_short, timeout: Duration) -> io::Result<()> { +fn wait_fd(fd: c_int, events: c_short, timeout: Option) -> io::Result<()> { use libc::{EINTR, EPIPE, EIO}; let mut fds = vec!(pollfd { fd: fd, events: events, revents: 0 }); @@ -72,7 +72,7 @@ fn wait_fd(fd: c_int, events: c_short, timeout: Duration) -> io::Result<()> { #[cfg(target_os = "linux")] #[inline] -fn do_poll(fds: &mut Vec, timeout: Duration) -> c_int { +fn do_poll(fds: &mut Vec, timeout: Option) -> c_int { use std::ptr; use libc::c_void; @@ -86,31 +86,44 @@ fn do_poll(fds: &mut Vec, timeout: Duration) -> c_int { fn ppoll(fds: *mut pollfd, nfds: nfds_t, timeout_ts: *mut libc::timespec, sigmask: *const sigset_t) -> c_int; } - let mut timeout_ts = libc::timespec { - tv_sec: timeout.as_secs() as libc::time_t, - tv_nsec: timeout.subsec_nanos() as libc::c_long, - }; + if let Some(timeout) = timeout { + let mut timeout_ts = libc::timespec { + tv_sec: timeout.as_secs() as libc::time_t, + tv_nsec: timeout.subsec_nanos() as libc::c_long, + }; - unsafe { - ppoll((&mut fds[..]).as_mut_ptr(), - fds.len() as nfds_t, - &mut timeout_ts, - ptr::null()) + unsafe { + ppoll((&mut fds[..]).as_mut_ptr(), + fds.len() as nfds_t, + &mut timeout_ts, + ptr::null()) + } + } else { + unsafe { + ppoll((&mut fds[..]).as_mut_ptr(), + fds.len() as nfds_t, + ptr::null_mut(), + ptr::null()) + } } } #[cfg(not(target_os = "linux"))] #[inline] -fn do_poll(fds: &mut Vec, timeout: Duration) -> c_int { +fn do_poll(fds: &mut Vec, timeout: Option) -> c_int { extern "C" { fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int; } - let milliseconds = timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000; + let milliseconds = if let Some(timeout) = timeout { + (timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000) as c_int + } else { + -1 + }; unsafe { poll((&mut fds[..]).as_mut_ptr(), fds.len() as nfds_t, - milliseconds as c_int) + milliseconds) } } diff --git a/serial-unix/src/tty.rs b/serial-unix/src/tty.rs index 1beddc0..e86d037 100644 --- a/serial-unix/src/tty.rs +++ b/serial-unix/src/tty.rs @@ -30,7 +30,7 @@ const O_NOCTTY: c_int = 0; /// The port will be closed when the value is dropped. pub struct TTYPort { fd: RawFd, - timeout: Duration, + timeout: Option, } impl TTYPort { @@ -65,7 +65,7 @@ impl TTYPort { let mut port = TTYPort { fd: fd, - timeout: Duration::from_millis(100), + timeout: None, }; // get exclusive access to device @@ -205,11 +205,11 @@ impl SerialDevice for TTYPort { Ok(()) } - fn timeout(&self) -> Duration { + fn timeout(&self) -> Option { self.timeout } - fn set_timeout(&mut self, timeout: Duration) -> core::Result<()> { + fn set_timeout(&mut self, timeout: Option) -> core::Result<()> { self.timeout = timeout; Ok(()) } diff --git a/serial-windows/src/com.rs b/serial-windows/src/com.rs index ba1b0cb..8b54033 100644 --- a/serial-windows/src/com.rs +++ b/serial-windows/src/com.rs @@ -160,23 +160,29 @@ impl SerialDevice for COMPort { } } - fn timeout(&self) -> Duration { + fn timeout(&self) -> Option { self.timeout } - fn set_timeout(&mut self, timeout: Duration) -> core::Result<()> { - let milliseconds = timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000; + fn set_timeout(&mut self, timeout: Option) -> core::Result<()> { + if let Some(timeout) = timeout { + let milliseconds = timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000; - let timeouts = COMMTIMEOUTS { - ReadIntervalTimeout: 0, - ReadTotalTimeoutMultiplier: 0, - ReadTotalTimeoutConstant: milliseconds as DWORD, - WriteTotalTimeoutMultiplier: 0, - WriteTotalTimeoutConstant: 0, - }; + let timeouts = COMMTIMEOUTS { + ReadIntervalTimeout: 0, + ReadTotalTimeoutMultiplier: 0, + ReadTotalTimeoutConstant: milliseconds as DWORD, + WriteTotalTimeoutMultiplier: 0, + WriteTotalTimeoutConstant: 0, + }; - if unsafe { SetCommTimeouts(self.handle, &timeouts) } == 0 { - return Err(error::last_os_error()); + if unsafe { SetCommTimeouts(self.handle, &timeouts) } == 0 { + return Err(error::last_os_error()); + } + } else { + if unsafe { SetCommTimeouts(self.handle, ptr::null()) } == 0 { + return Err(error::last_os_error()); + } } self.timeout = timeout; diff --git a/serial/README.md b/serial/README.md index 6f638da..af334a1 100644 --- a/serial/README.md +++ b/serial/README.md @@ -59,7 +59,7 @@ fn interact(port: &mut T) -> io::Result<()> { Ok(()) })); - try!(port.set_timeout(Duration::from_millis(1000))); + try!(port.set_timeout(Some(Duration::from_millis(1000)))); let mut buf: Vec = (0..255).collect(); diff --git a/serial/examples/probe_pins.rs b/serial/examples/probe_pins.rs index 0e974b5..3cc2949 100644 --- a/serial/examples/probe_pins.rs +++ b/serial/examples/probe_pins.rs @@ -24,7 +24,7 @@ fn main() { fn probe_pins(port: &mut T) -> serial::Result<()> { try!(port.configure(&SETTINGS)); - try!(port.set_timeout(Duration::from_millis(100))); + try!(port.set_timeout(Some(Duration::from_millis(100)))); try!(port.set_rts(false)); try!(port.set_dtr(false)); diff --git a/serial/examples/read_write.rs b/serial/examples/read_write.rs index 4670611..17a79f1 100644 --- a/serial/examples/read_write.rs +++ b/serial/examples/read_write.rs @@ -25,7 +25,7 @@ fn main() { fn interact(port: &mut T) -> serial::Result<()> { try!(port.configure(&SETTINGS)); - try!(port.set_timeout(Duration::from_secs(1))); + try!(port.set_timeout(Some(Duration::from_secs(1)))); let mut buf: Vec = (0..255).collect();