chiark / gitweb /
Add a thread lock to the machineCom _sendCommand
authorYouness Alaoui <kakaroto@kakaroto.homelinux.net>
Tue, 8 Dec 2015 19:52:49 +0000 (14:52 -0500)
committerYouness Alaoui <kakaroto@kakaroto.homelinux.net>
Tue, 8 Dec 2015 19:52:49 +0000 (14:52 -0500)
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

index e6ce8c11d0f2e537f134b8e9b6754b265a778593..90c9d3eb2c4cc0ff4f6f2d2e69bff36982e6975b 100644 (file)
@@ -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):