posix: fix PosixPollSerial with timeout=None and add cancel support
fixes #265
diff --git a/serial/serialposix.py b/serial/serialposix.py
index afe5062..3ac6283 100644
--- a/serial/serialposix.py
+++ b/serial/serialposix.py
@@ -733,21 +733,28 @@
if not self.is_open:
raise portNotOpenError
read = bytearray()
+ timeout = Timeout(self._timeout)
poll = select.poll()
poll.register(self.fd, select.POLLIN | select.POLLERR | select.POLLHUP | select.POLLNVAL)
+ poll.register(self.pipe_abort_read_r, select.POLLIN | select.POLLERR | select.POLLHUP | select.POLLNVAL)
if size > 0:
while len(read) < size:
# print "\tread(): size",size, "have", len(read) #debug
# wait until device becomes ready to read (or something fails)
- for fd, event in poll.poll(self._timeout * 1000):
+ for fd, event in poll.poll(None if timeout.is_infinite else (timeout.time_left() * 1000)):
+ if fd == self.pipe_abort_read_r:
+ break
if event & (select.POLLERR | select.POLLHUP | select.POLLNVAL):
raise SerialException('device reports error (poll)')
# we don't care if it is select.POLLIN or timeout, that's
# handled below
+ if fd == self.pipe_abort_read_r:
+ os.read(self.pipe_abort_read_r, 1000)
+ break
buf = os.read(self.fd, size - len(read))
read.extend(buf)
- if ((self._timeout is not None and self._timeout >= 0) or
- (self._inter_byte_timeout is not None and self._inter_byte_timeout > 0)) and not buf:
+ if timeout.expired() \
+ or (self._inter_byte_timeout is not None and self._inter_byte_timeout > 0) and not buf:
break # early abort on timeout
return bytes(read)