--- a/Beremiz_service.py Fri Jan 25 14:06:11 2019 +0100
+++ b/Beremiz_service.py Tue Jan 29 09:14:47 2019 +0100
@@ -30,7 +30,7 @@
-from threading import Thread, Semaphore, Lock
+from threading import Thread, Semaphore, Lock, currentThread from builtins import str as text
from past.builtins import execfile
@@ -414,10 +414,11 @@
reactor.registerWxApp(app)
+twisted_reactor_thread_id = None wx_eval_lock = Semaphore(0)
- # FIXME : beware wx mainloop is _not_ running in main thread
- # main_thread = currentThread()
def statuschangeTskBar(status):
wx.CallAfter(taskbar_instance.UpdateIcon, status)
@@ -430,15 +431,23 @@
def evaluator(tocall, *args, **kwargs):
- # FIXME : should implement anti-deadlock
- # if main_thread == currentThread():
- # # avoid dead lock if called from the wx mainloop
- # return default_evaluator(tocall, *args, **kwargs)
- o = type('', (object,), dict(call=(tocall, args, kwargs), res=None))
- wx.CallAfter(wx_evaluator, o)
+ # To prevent deadlocks, check if current thread is not one of the UI + # UI threads can be either the one from WX main loop or + # worker thread from twisted "threadselect" reactor + current_id = currentThread().ident + if ui_thread is not None \ + and ui_thread.ident != current_id \ + and (not havetwisted or ( + twisted_reactor_thread_id is not None + and twisted_reactor_thread_id != current_id)): + o = type('', (object,), dict(call=(tocall, args, kwargs), res=None)) + wx.CallAfter(wx_evaluator, o) + # avoid dead lock if called from the wx mainloop + return default_evaluator(tocall, *args, **kwargs) evaluator = default_evaluator
@@ -560,7 +569,10 @@
# This order ui loop to unblock main thread when ready.
- reactor.callLater(0, ui_thread_started.release)
+ def signal_uithread_started(): + twisted_reactor_thread_id = currentThread().ident + ui_thread_started.release() + reactor.callLater(0, signal_uithread_started) wx.CallAfter(ui_thread_started.release)