From 568fcbf54799d29ad05ac74b072e270aebd95372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 7 Aug 2014 18:07:19 +0200 Subject: [PATCH] Don't close serial port before switching to state "closed serial port" Depending on what was happening in the monitoring thread this could lead to an attempt to write to the already closed port, logging an error and killing the interface in the process. Also fixed a timing issue in the state reporting towards the frontend, state updates and readings for clients are now wrapped in a mutex Closes #492 (cherry picked from commit 11fb18f) --- src/octoprint/printer.py | 25 ++++++++++++++----------- src/octoprint/util/comm.py | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/octoprint/printer.py b/src/octoprint/printer.py index f992b78d..fd48b743 100644 --- a/src/octoprint/printer.py +++ b/src/octoprint/printer.py @@ -677,6 +677,7 @@ class StateMonitor(object): self._offsets = {} self._changeEvent = threading.Event() + self._stateMutex = threading.Lock() self._lastUpdate = time.time() self._worker = threading.Thread(target=self._work) @@ -706,8 +707,9 @@ class StateMonitor(object): self._changeEvent.set() def setState(self, state): - self._state = state - self._changeEvent.set() + with self._stateMutex: + self._state = state + self._changeEvent.set() def setJobData(self, jobData): self._jobData = jobData @@ -725,16 +727,17 @@ class StateMonitor(object): while True: self._changeEvent.wait() - now = time.time() - delta = now - self._lastUpdate - additionalWaitTime = self._ratelimit - delta - if additionalWaitTime > 0: - time.sleep(additionalWaitTime) + with self._stateMutex: + now = time.time() + delta = now - self._lastUpdate + additionalWaitTime = self._ratelimit - delta + if additionalWaitTime > 0: + time.sleep(additionalWaitTime) - data = self.getCurrentData() - self._updateCallback(data) - self._lastUpdate = time.time() - self._changeEvent.clear() + data = self.getCurrentData() + self._updateCallback(data) + self._lastUpdate = time.time() + self._changeEvent.clear() def getCurrentData(self): return { diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index a15eb4de..98cb0eb9 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -340,11 +340,11 @@ class MachineCom(object): def close(self, isError = False): printing = self.isPrinting() or self.isPaused() if self._serial is not None: - self._serial.close() 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"]):