Fix EINTR with new fragless code
authorJack Miller <jack@codezen.org>
Sun, 5 Jul 2015 07:16:38 +0000 (02:16 -0500)
committerJack Miller <jack@codezen.org>
Sun, 5 Jul 2015 21:50:34 +0000 (16:50 -0500)
Returning used to just postpone the current fragment, now that we know
the size and have no fragments, we can just properly retry.

canto_next/protocol.py

index fe8f627..0dffe0c 100644 (file)
@@ -240,21 +240,23 @@ class CantoSocket:
             return select.POLLHUP
         if e & (select.POLLIN | select.POLLPRI):
             message = ""
-            try:
-                size = struct.unpack('!q', conn.recv(8))[0]
-                while size:
+            size = struct.unpack('!q', conn.recv(8))[0]
+            while size:
+                try:
                     frag = conn.recv(min((4096, size)))
                     size -= len(frag)
                     message += frag.decode()
-            except Exception as e:
-                if e.args[0] == errno.EINTR:
-                    return
-                log.error("Error receiving: %s" % e)
-                log.error("Interpreting as HUP")
-                return select.POLLHUP
+                except Exception as e:
+                    if e.args[0] == errno.EINTR:
+                        continue
+
+                    log.error("Error receiving: %s" % e)
+                    log.error("Interpreting as HUP")
+                    return select.POLLHUP
 
             # Never get POLLRDHUP on INET sockets, so
             # use POLLIN with no data as POLLHUP
+
             if not message:
                 log.debug("Read POLLIN with no data")
                 return select.POLLHUP