From 7cf23e34d3ca118d5d3f790c224bdf8a37a27f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vilhelm=20Bergs=C3=B8e?= Date: Tue, 5 Dec 2023 20:33:33 +0100 Subject: [PATCH 1/2] fix: handle EINTR: Attempt at handling EINTR in the case of a system call interrupt when polling for events. --- src/device.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/device.rs b/src/device.rs index 4b62721..a5c78ff 100644 --- a/src/device.rs +++ b/src/device.rs @@ -394,7 +394,13 @@ impl Handle { timeout, ) } { - -1 => Err(io::Error::last_os_error()), + -1 => { + let e = io::Error::last_os_error(); + match e.kind() { + io::ErrorKind::Interrupted => self.poll(events, timeout), + _ => Err(e), + } + }, ret => { // A return value of zero means that we timed out. A positive value signifies the // number of fds with non-zero revents fields (aka I/O activity). From 351e1c4ee3bf73f6d9bf2ae49c5dc2c2dabf2df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vilhelm=20Bergs=C3=B8e?= Date: Tue, 5 Dec 2023 21:51:36 +0100 Subject: [PATCH 2/2] re: device: poll() on interrupts (EINTR): re; now using loop --- src/device.rs | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/device.rs b/src/device.rs index a5c78ff..8c4c6f6 100644 --- a/src/device.rs +++ b/src/device.rs @@ -382,30 +382,32 @@ impl Handle { /// A value of zero returns immedately, even if the fd is not ready. /// A negative value means infinite timeout (blocking). pub fn poll(&self, events: i16, timeout: i32) -> io::Result { - match unsafe { - libc::poll( - [libc::pollfd { - fd: self.fd, - events, - revents: 0, - }] - .as_mut_ptr(), - 1, - timeout, - ) - } { - -1 => { - let e = io::Error::last_os_error(); - match e.kind() { - io::ErrorKind::Interrupted => self.poll(events, timeout), - _ => Err(e), + loop { + return match unsafe { + libc::poll( + [libc::pollfd { + fd: self.fd, + events, + revents: 0, + }] + .as_mut_ptr(), + 1, + timeout, + ) + } { + -1 => { + let e = io::Error::last_os_error(); + match e.kind() { + io::ErrorKind::Interrupted => continue, + _ => Err(e), + } + }, + ret => { + // A return value of zero means that we timed out. A positive value signifies the + // number of fds with non-zero revents fields (aka I/O activity). + assert!(ret == 0 || ret == 1); + Ok(ret) } - }, - ret => { - // A return value of zero means that we timed out. A positive value signifies the - // number of fds with non-zero revents fields (aka I/O activity). - assert!(ret == 0 || ret == 1); - Ok(ret) } } }