USBPrinterOutputDevice creates a thread for handling the printing. However, the code is not implemented in a thread-safe manner. In particular:
- Certain data structures are shared between the UI thread and the print thread, yet synchronized access is not maintained through the use of Thread.Lock() and Thread.Unlock(). Examples include:
- The print thread currently calls methods which modify UI elements. These calls may or may not be thread-safe. Examples of potentially dangerous method calls include:
It is interesting to note that Cura 1 solved this problem by having a separate process (rather than a thread) handle the printing and information was transferred via sockets. Although the use of a Thread in Cura 2 is an acceptable solution, access to shared data and message passing ought to still be done in a thread safe manner.
Issue #1 is the most serious deficiency, but could probably be relatively easily solved by using Thread.Lock() within USBPrinterOutputDevice. Issue #2 is harder to solve may require replacing method calls with a message queue or PyQT signal and slots.
The current thread-unsafe code is will probably work "well-enough", but there is a risk of occasional errors or crashes until the problems are resolved. It is possible that certain issues, such as T1156 and T918, may be related.