OpenCyphal / pycyphal

Python implementation of the Cyphal protocol stack.
https://pycyphal.readthedocs.io/
MIT License
123 stars 106 forks source link

Don't call close more than once in slcan driver #42

Closed mkeeter closed 6 years ago

mkeeter commented 6 years ago

The slcan driver can misbehave when close() is called more than once on a node. This is a problem, because close() is called in the SLCAN destructor, even if it was already called by a context manager.

I tested with the following script:

import uavcan

for i in range(25):
    node = uavcan.make_node('/dev/cu.usbmodem14431', node_id=3)
    node.close()

And see the following error message once the GC starts reclaiming older nodes:

Exception ignored in: <function SLCAN.__del__ at 0x1039841e0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/uavcan/driver/slcan.py", line 712, in __del__
    self.close()
  File "/usr/local/lib/python3.7/site-packages/uavcan/driver/slcan.py", line 688, in close
    if self._proc.is_alive():
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/process.py", line 151, in is_alive
    assert self._parent_pid == os.getpid(), 'can only test a child process'
AssertionError: can only test a child process

This PR fixes the issue by skipping the call to close() if a flag is already set.