Beremiz_service.py
branchwxPython4
changeset 3584 8a54fd58a552
parent 3443 a47d9debb0d9
child 3585 efdefbad49eb
--- a/Beremiz_service.py	Sat Aug 13 16:12:39 2022 +0200
+++ b/Beremiz_service.py	Tue Aug 16 19:52:49 2022 +0200
@@ -435,8 +435,6 @@
     if havewx:
         reactor.registerWxApp(app)
 
-twisted_reactor_thread_id = None
-ui_thread = None
 
 if havewx:
     wx_eval_lock = Semaphore(0)
@@ -451,24 +449,18 @@
         obj.res = default_evaluator(tocall, *args, **kwargs)
         wx_eval_lock.release()
 
+    main_thread_id = currentThread().ident
     def evaluator(tocall, *args, **kwargs):
-        # 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
+        # To prevent deadlocks, check if current thread is not one already main
         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)):
-
+        if main_thread_id != current_id:
             o = type('', (object,), dict(call=(tocall, args, kwargs), res=None))
             wx.CallAfter(wx_evaluator, o)
             wx_eval_lock.acquire()
             return o.res
         else:
-            # avoid dead lock if called from the wx mainloop
+            # avoid dead lock if called from main : do job immediately
             return default_evaluator(tocall, *args, **kwargs)
 else:
     evaluator = default_evaluator
@@ -555,13 +547,39 @@
         except Exception:
             LogMessageAndException(_("WAMP client startup failed. "))
 
+if havetwisted or havewx:
+    if havetwisted:
+        # reactor._installSignalHandlersAgain()
+        waker_func = reactor._runInMainThread
+        def ui_blocking_call():
+            # FIXME: had to disable SignaHandlers install because
+            # signal not working in non-main thread
+            reactor.run(installSignalHandlers=False)
+    else:
+        waker_func = wx.CallAfter
+        ui_blocking_call = app.MainLoop
+
+    def ui_launched_report():
+        # IDE expects to see that string to stop waiting for runtime
+        # to be ready and connnect to it.
+        print("UI thread started successfully.")
+
+    # This orders ui loop to signal when ready on Stdout
+    if havetwisted:
+        reactor.callLater(0, ui_launched_report)
+    else:
+        wx.CallAfter(ui_launched_report)
+
+
+pyro_thread = None
+
 def FirstWorkerJob():
     """
     RPC through pyro/wamp/UI may lead to delegation to Worker,
     then this function ensures that Worker is already
     created when pyro starts
     """
-    global pyro_thread, pyroserver, ui_thread, reactor, twisted_reactor_thread_id
+    global pyro_thread, pyroserver
 
     pyro_thread_started = Lock()
     pyro_thread_started.acquire()
@@ -581,41 +599,19 @@
     sys.stdout.write(_("Current working directory :") + WorkingDir + "\n")
     sys.stdout.flush()
 
-    if not (havetwisted or havewx):
-        return
-
-    ui_thread_started = Lock()
-    ui_thread_started.acquire()
-    if havetwisted:
-        # reactor._installSignalHandlersAgain()
-        def ui_thread_target():
-            # FIXME: had to disable SignaHandlers install because
-            # signal not working in non-main thread
-            reactor.run(installSignalHandlers=False)
+    runtime.GetPLCObjectSingleton().AutoLoad(autostart)
+
+try:
+    if havetwisted or havewx:
+        # worker that copes with wx and (wx)reactor
+        runtime.MainWorker.interleave(waker_func, FirstWorkerJob)
+        ui_blocking_call()
+        runtime.MainWorker.stop()
+
     else:
-        ui_thread_target = app.MainLoop
-
-    ui_thread = Thread(target=ui_thread_target, name="UIThread")
-    ui_thread.start()
-
-    # This order ui loop to unblock main thread when ready.
-    if havetwisted:
-        def signal_uithread_started():
-            global twisted_reactor_thread_id
-            twisted_reactor_thread_id = currentThread().ident
-            ui_thread_started.release()
-        reactor.callLater(0, signal_uithread_started)
-    else:
-        wx.CallAfter(ui_thread_started.release)
-
-    # Wait for ui thread to be effective
-    ui_thread_started.acquire()
-    print("UI thread started successfully.")
-
-    runtime.GetPLCObjectSingleton().AutoLoad(autostart)
-
-try:
-    runtime.MainWorker.runloop(FirstWorkerJob)
+        # blocking worker loop
+        runtime.MainWorker.runloop(FirstWorkerJob)
+
 except KeyboardInterrupt:
     pass
 
@@ -631,9 +627,7 @@
 
 if havetwisted:
     reactor.stop()
-    ui_thread.join()
 elif havewx:
     app.ExitMainLoop()
-    ui_thread.join()
 
 sys.exit(0)