From 7f10c317f1950c0b611d68d15f44b00c3ad9f852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 13 Aug 2015 17:15:01 +0200 Subject: [PATCH] Properly handle serial close on Macs 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 (cherry picked from commit c829b27) --- src/octoprint/util/comm.py | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index e36e6e92..6f3cd1e4 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -151,6 +151,7 @@ class MachineCom(object): self._long_running_command = False self._heating = False + self._connection_closing = False self._timeout = None @@ -400,11 +401,15 @@ class MachineCom(object): printing = self.isPrinting() or self.isPaused() if self._serial is not None: + try: + self._serial.close() + except: + self._logger.exception("Error while trying to close serial port") + isError = True if isError: self._changeState(self.STATE_CLOSED_WITH_ERROR) else: self._changeState(self.STATE_CLOSED) - self._serial.close() self._serial = None if settings().get(["feature", "sdSupport"]): @@ -1317,15 +1322,17 @@ class MachineCom(object): 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(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(True) return None if ret == '': #self._log("Recv: TIMEOUT") @@ -1635,6 +1642,9 @@ class MachineCom(object): 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') @@ -1643,15 +1653,17 @@ class MachineCom(object): 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(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(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(True) ##~~ command handlers