Skip to content

Commit

Permalink
Properly handle serial close on Macs
Browse files Browse the repository at this point in the history
Readline could still be stuck in a read loop, leading to an exception on Mac
when closing the connection from another thread. This should now be captured
correctly.

Fixes #1021
  • Loading branch information
foosel committed Aug 13, 2015
1 parent c00b136 commit c829b27
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/octoprint/util/comm.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def __init__(self, port = None, baudrate=None, callbackObject=None, printerProfi

self._long_running_command = False
self._heating = False
self._connection_closing = False

self._timeout = None

Expand Down Expand Up @@ -429,6 +430,10 @@ def close(self, is_error=False, wait=True, *args, **kwargs):
# legacy parameters
is_error = kwargs.get("isError", is_error)

if self._connection_closing:
return
self._connection_closing = True

if self._temperature_timer is not None:
try:
self._temperature_timer.cancel()
Expand All @@ -453,7 +458,13 @@ def deactivate_monitoring_and_send_queue():
self._send_queue.join()

deactivate_monitoring_and_send_queue()
self._serial.close()

try:
self._serial.close()
except:
self._logger.exception("Error while trying to close serial port")
is_error = True

if is_error:
self._changeState(self.STATE_CLOSED_WITH_ERROR)
else:
Expand Down Expand Up @@ -1379,15 +1390,17 @@ def _handleErrors(self, line):
return line

def _readline(self):
if self._serial == None:
if self._serial == None or self._connection_closing:
return None

try:
ret = self._serial.readline()
except:
self._logger.exception("Unexpected error while reading from serial port")
self._log("Unexpected error while reading serial port, please consult octoprint.log for details: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(is_error=True)
if not self._connection_closing:
self._logger.exception("Unexpected error while reading from serial port")
self._log("Unexpected error while reading serial port, please consult octoprint.log for details: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(is_error=True)
return None
if ret == '':
#self._log("Recv: TIMEOUT")
Expand Down Expand Up @@ -1711,6 +1724,9 @@ def _doSendWithChecksum(self, cmd, lineNumber):
self._doSendWithoutChecksum(commandToSend)

def _doSendWithoutChecksum(self, cmd):
if self._serial is None or self._connection_closing:
return

self._log("Send: %s" % cmd)
try:
self._serial.write(cmd + '\n')
Expand All @@ -1719,15 +1735,17 @@ def _doSendWithoutChecksum(self, cmd):
try:
self._serial.write(cmd + '\n')
except:
if not self._connection_closing:
self._logger.exception("Unexpected error while writing to serial port")
self._log("Unexpected error while writing to serial port: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(is_error=True)
except:
if not self._connection_closing:
self._logger.exception("Unexpected error while writing to serial port")
self._log("Unexpected error while writing to serial port: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(is_error=True)
except:
self._logger.exception("Unexpected error while writing to serial port")
self._log("Unexpected error while writing to serial port: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(is_error=True)

##~~ command handlers

Expand Down

0 comments on commit c829b27

Please sign in to comment.