diff --git a/serial_asyncio/__init__.py b/serial_asyncio/__init__.py index e173b56..aeb10e0 100644 --- a/serial_asyncio/__init__.py +++ b/serial_asyncio/__init__.py @@ -61,11 +61,18 @@ def __init__(self, loop, protocol, serial_instance): self._poll_wait_time = 0.0005 self._max_out_waiting = 1024 - # XXX how to support url handlers too + try: + self._serial.fileno() + self._has_fileno = True + except: + self._has_fileno = False # Asynchronous I/O requires non-blocking devices self._serial.timeout = 0 - self._serial.write_timeout = 0 + try: + self._serial.write_timeout = 0 + except: + pass # best effort, not supported by all Serial implementations # These two callbacks will be enqueued in a FIFO queue by asyncio loop.call_soon(protocol.connection_made, self) @@ -284,60 +291,52 @@ def _write_ready(self): self._maybe_resume_protocol() assert self._has_writer - if os.name == "nt": - def _poll_read(self): - if self._has_reader and not self._closing: - try: - self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read) - if self.serial.in_waiting: - self._read_ready() - except serial.SerialException as exc: - self._fatal_error(exc, 'Fatal write error on serial transport') - - def _ensure_reader(self): - if not self._has_reader and not self._closing: + def _poll_read(self): + if self._has_reader and not self._closing: + try: self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read) - - def _remove_reader(self): - if self._has_reader: - self._has_reader.cancel() - self._has_reader = False - - def _poll_write(self): - if self._has_writer and not self._closing: - self._has_writer = self._loop.call_later(self._poll_wait_time, self._poll_write) - if self.serial.out_waiting < self._max_out_waiting: - self._write_ready() - - def _ensure_writer(self): - if not self._has_writer and not self._closing: - self._has_writer = self._loop.call_soon(self._poll_write) - - def _remove_writer(self): - if self._has_writer: - self._has_writer.cancel() - self._has_writer = False - - else: - def _ensure_reader(self): - if (not self._has_reader) and (not self._closing): + if self.serial.in_waiting: + self._read_ready() + except serial.SerialException as exc: + self._fatal_error(exc, 'Fatal write error on serial transport') + + def _ensure_reader(self): + if not self._has_reader and not self._closing: + if not self._has_fileno: + self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read) + else: self._loop.add_reader(self._serial.fileno(), self._read_ready) self._has_reader = True - def _remove_reader(self): - if self._has_reader: + def _remove_reader(self): + if self._has_reader: + if not self._has_fileno: + self._has_reader.cancel() + else: self._loop.remove_reader(self._serial.fileno()) - self._has_reader = False + self._has_reader = False - def _ensure_writer(self): - if (not self._has_writer) and (not self._closing): - self._loop.add_writer(self._serial.fileno(), self._write_ready) + def _poll_write(self): + if self._has_writer and not self._closing: + self._has_writer = self._loop.call_later(self._poll_wait_time, self._poll_write) + if not hasattr(self.serial, "out_waiting") or self.serial.out_waiting < self._max_out_waiting: + self._write_ready() + + def _ensure_writer(self): + if not self._has_writer and not self._closing: + if not self._has_fileno: + self._has_writer = self._loop.call_soon(self._poll_write) + else: + self._loop.add_writer(self.serial.fileno(), self._write_ready) self._has_writer = True - def _remove_writer(self): - if self._has_writer: + def _remove_writer(self): + if self._has_writer: + if not self._has_fileno: + self._has_writer.cancel() + else: self._loop.remove_writer(self._serial.fileno()) - self._has_writer = False + self._has_writer = False def _set_write_buffer_limits(self, high=None, low=None): """Ensure consistent write-buffer limits."""