Skip to content

Commit 6738f89

Browse files
authored
fix multiple writers race on windows (#70)
* fix multiple writers race * fix semantics of out_waiting * remove unnecessary delay on first write on windows
1 parent 7623ac9 commit 6738f89

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

serial_asyncio/__init__.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def __init__(self, loop, protocol, serial_instance):
5757
self._has_reader = False
5858
self._has_writer = False
5959
self._poll_wait_time = 0.0005
60+
self._max_out_waiting = 1024
6061

6162
# XXX how to support url handlers too
6263

@@ -283,34 +284,36 @@ def _write_ready(self):
283284

284285
if os.name == "nt":
285286
def _poll_read(self):
286-
if self._has_reader:
287+
if self._has_reader and not self._closing:
287288
try:
289+
self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read)
288290
if self.serial.in_waiting:
289-
self._loop.call_soon(self._read_ready)
290-
self._loop.call_later(self._poll_wait_time, self._poll_read)
291+
self._read_ready()
291292
except serial.SerialException as exc:
292293
self._fatal_error(exc, 'Fatal write error on serial transport')
293294

294295
def _ensure_reader(self):
295-
if (not self._has_reader) and (not self._closing):
296-
self._loop.call_later(self._poll_wait_time, self._poll_read)
297-
self._has_reader = True
296+
if not self._has_reader and not self._closing:
297+
self._has_reader = self._loop.call_later(self._poll_wait_time, self._poll_read)
298298

299299
def _remove_reader(self):
300+
if self._has_reader:
301+
self._has_reader.cancel()
300302
self._has_reader = False
301303

302304
def _poll_write(self):
303-
if self._has_writer:
304-
if self.serial.out_waiting:
305-
self._loop.call_soon(self._write_ready)
306-
self._loop.call_later(self._poll_wait_time, self._poll_write)
305+
if self._has_writer and not self._closing:
306+
self._has_writer = self._loop.call_later(self._poll_wait_time, self._poll_write)
307+
if self.serial.out_waiting < self._max_out_waiting:
308+
self._write_ready()
307309

308310
def _ensure_writer(self):
309-
if (not self._has_writer) and (not self._closing):
310-
self._loop.call_later(self._poll_wait_time, self._poll_write)
311-
self._has_writer = True
311+
if not self._has_writer and not self._closing:
312+
self._has_writer = self._loop.call_soon(self._poll_write)
312313

313314
def _remove_writer(self):
315+
if self._has_writer:
316+
self._has_writer.cancel()
314317
self._has_writer = False
315318

316319
else:

0 commit comments

Comments
 (0)