From 6be9647305ea6f0888bf41c26b24ccc3aece9d05 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Mon, 15 Mar 2021 12:59:19 -0300 Subject: [PATCH] Fixes unsafe multithread mechanism in button_run - Fixes #412 - On Linux it fixes the error: ``` [xcb] Unknown sequence number while processing queue [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. python3: ../../src/xcb_io.c:269: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed. ``` - The solution is just a copy & paste from StackOverflow: https://stackoverflow.com/questions/32410359/threading-in-wxpython - From what I interpret the main point here is the use of wx.CallAfter --- kicost/kicost_gui.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/kicost/kicost_gui.py b/kicost/kicost_gui.py index 231e11fc9..bb2dcb9c7 100644 --- a/kicost/kicost_gui.py +++ b/kicost/kicost_gui.py @@ -41,7 +41,7 @@ import sys import os import subprocess # To access OS commands and run in the shell. -import threading +from threading import Thread import time # To elapse time. import tempfile # To create the temporary log file. from datetime import datetime # To create the log name, when asked to save. @@ -96,6 +96,18 @@ kicostPath = os.path.dirname(os.path.abspath(__file__)) # Application dir. +# ====================================================================== +class ChildThread(Thread): + """ Helper class to safetly call the run action """ + def __init__(self, myframe): + """Init Worker Thread Class.""" + Thread.__init__(self) + self.myframe = myframe + + def run(self): + wx.CallAfter(self.myframe.run) + + # ====================================================================== def open_file(filepath): '''@brief Open a file with the default application in different OSs. @@ -714,10 +726,9 @@ def addFile(self, filesName): def button_run(self, event): ''' @brief Call to run KiCost.''' event.Skip() - # self.run() - # wx.CallLater(10, self.run) # Necessary to not '(core dumped)' with wxPython. - t = threading.Thread(target=self.run) # , args=[self]) - t.start() + self.child = ChildThread(myframe=self) + self.child.daemon = True + self.child.start() # ---------------------------------------------------------------------- # @anythread