chiark / gitweb /
packetframe: Fuse: Do not persist EINTR or EWOULDBLOCK
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 17 May 2021 09:45:08 +0000 (10:45 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 17 May 2021 10:07:53 +0000 (11:07 +0100)
Fusing EINTR is particularly toxic.  BufReader retries.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/packetframe.rs

index 2c0b3bf2e27f7260ad8ce2a0587b6d6d8c6673a4..1bc227c896a595b46b0ec4138c91d8c28053ffe1 100644 (file)
@@ -129,7 +129,12 @@ impl<RW> Fuse<RW> {
   {
     let inner = self.get()?;
     let r = f(inner);
-    if let Err(e) = &r {
+    // These are often retried, or treated specially, by higher
+    // layers.  EWOULDBLOCK can generally only occur as an actual
+    // error if the fd is wrongly made nonblocking.
+    if let Err(e) = r {
+      if e.kind() ==  ErrorKind::Interrupted ||
+         e.kind() ==  ErrorKind::WouldBlock { throw!(e) }
       let error = Broken {
         msg: e.to_string(),
         kind: e.kind(),
@@ -141,6 +146,7 @@ impl<RW> Fuse<RW> {
       self.inner.as_mut().map(|_|()).unwrap_err().inner = Some(
         inner.map_err(|e| e.error).unwrap()
       );
+      throw!(e);
     }
     r?
   }