From a348b3a92a7ea3fd6d09fb630d5a721a5fba52bf Mon Sep 17 00:00:00 2001 From: Youness Alaoui Date: Tue, 8 Dec 2015 14:52:49 -0500 Subject: [PATCH] Add a thread lock to the machineCom _sendCommand This is the real cause for the serial WriteTimeout on Windows. It looks like the win32 pyserial has a concurrency issue and is not thread-safe, so when we receive commands from the UI (such as 'print', 'pause', 'resume', 'temp' or custom gcode), they get executed from the main thread and if we receive an 'ok' from the firmware on the serial monitor thread, it can cause the next command to be sent from the monitor thread causing data to be written to serial from two threads, which causes pyserial to just cancel both writes with a WriteTimeoutException. Fixes T332 --- Cura/util/machineCom.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Cura/util/machineCom.py b/Cura/util/machineCom.py index e6ce8c11..90c9d3eb 100644 --- a/Cura/util/machineCom.py +++ b/Cura/util/machineCom.py @@ -203,7 +203,8 @@ class MachineCom(object): self._heatupWaitTimeLost = 0.0 self._printStartTime100 = None self._currentCommands = [] - + + self._thread_lock = threading.Lock() self.thread = threading.Thread(target=self._monitor) self.thread.daemon = True self.thread.start() @@ -589,7 +590,9 @@ class MachineCom(object): self.close() def _sendCommand(self, cmd): + self._thread_lock.acquire(True) if self._serial is None: + self._thread_lock.release() return if 'M109' in cmd or 'M190' in cmd: self._heatupWaitStartTime = time.time() @@ -624,6 +627,7 @@ class MachineCom(object): self._log("Unexpected error while writing serial port: %s" % (getExceptionString())) self._errorValue = getExceptionString() self.close(True) + self._thread_lock.release() def _sendNext(self): if self._gcodePos >= len(self._gcodeList): -- 2.30.2