35 import threading |
35 import threading |
36 from threading import Thread, Semaphore, Lock, currentThread |
36 from threading import Thread, Semaphore, Lock, currentThread |
37 from builtins import str as text |
37 from builtins import str as text |
38 from past.builtins import execfile |
38 from past.builtins import execfile |
39 from six.moves import builtins |
39 from six.moves import builtins |
|
40 from functools import partial |
40 |
41 |
41 import runtime |
42 import runtime |
42 from runtime.PyroServer import PyroServer |
43 from runtime.PyroServer import PyroServer |
43 from runtime.xenomai import TryPreloadXenomai |
44 from runtime.xenomai import TryPreloadXenomai |
44 from runtime import LogMessageAndException |
45 from runtime import LogMessageAndException |
545 WC.RegisterWampClient(wampconf, PSKpath) |
546 WC.RegisterWampClient(wampconf, PSKpath) |
546 WC.RegisterWebSettings(NS) |
547 WC.RegisterWebSettings(NS) |
547 except Exception: |
548 except Exception: |
548 LogMessageAndException(_("WAMP client startup failed. ")) |
549 LogMessageAndException(_("WAMP client startup failed. ")) |
549 |
550 |
550 if havetwisted or havewx: |
|
551 if havetwisted: |
|
552 # reactor._installSignalHandlersAgain() |
|
553 waker_func = reactor._runInMainThread |
|
554 def ui_blocking_call(): |
|
555 # FIXME: had to disable SignaHandlers install because |
|
556 # signal not working in non-main thread |
|
557 reactor.run(installSignalHandlers=False) |
|
558 else: |
|
559 waker_func = wx.CallAfter |
|
560 ui_blocking_call = app.MainLoop |
|
561 |
|
562 def ui_launched_report(): |
|
563 # IDE expects to see that string to stop waiting for runtime |
|
564 # to be ready and connnect to it. |
|
565 print("UI thread started successfully.") |
|
566 |
|
567 # This orders ui loop to signal when ready on Stdout |
|
568 if havetwisted: |
|
569 reactor.callLater(0, ui_launched_report) |
|
570 else: |
|
571 wx.CallAfter(ui_launched_report) |
|
572 |
|
573 |
|
574 pyro_thread = None |
551 pyro_thread = None |
575 |
552 |
576 def FirstWorkerJob(): |
553 def FirstWorkerJob(): |
577 """ |
554 """ |
578 RPC through pyro/wamp/UI may lead to delegation to Worker, |
555 RPC through pyro/wamp/UI may lead to delegation to Worker, |
599 sys.stdout.write(_("Current working directory :") + WorkingDir + "\n") |
576 sys.stdout.write(_("Current working directory :") + WorkingDir + "\n") |
600 sys.stdout.flush() |
577 sys.stdout.flush() |
601 |
578 |
602 runtime.GetPLCObjectSingleton().AutoLoad(autostart) |
579 runtime.GetPLCObjectSingleton().AutoLoad(autostart) |
603 |
580 |
604 try: |
581 if havetwisted or havewx: |
605 if havetwisted or havewx: |
582 |
606 # worker that copes with wx and (wx)reactor |
583 waker_func = wx.CallAfter if havewx else partial(reactor.callLater,0) |
607 runtime.MainWorker.interleave(waker_func, FirstWorkerJob) |
584 |
608 ui_blocking_call() |
585 # This orders ui loop to signal when ready on Stdout |
609 runtime.MainWorker.stop() |
586 waker_func(print,"UI thread started successfully.") |
610 |
587 |
611 else: |
588 # worker that copes with wx and (wx)reactor |
|
589 runtime.MainWorker.interleave(waker_func, FirstWorkerJob) |
|
590 |
|
591 try: |
|
592 if havetwisted: |
|
593 reactor.run(installSignalHandlers=False) |
|
594 else: |
|
595 app.MainLoop |
|
596 except KeyboardInterrupt: |
|
597 pass |
|
598 |
|
599 runtime.MainWorker.stop() |
|
600 |
|
601 else: |
|
602 try: |
612 # blocking worker loop |
603 # blocking worker loop |
613 runtime.MainWorker.runloop(FirstWorkerJob) |
604 runtime.MainWorker.runloop(FirstWorkerJob) |
614 |
605 except KeyboardInterrupt: |
615 except KeyboardInterrupt: |
606 pass |
616 pass |
607 |
617 |
608 |
618 pyroserver.Quit() |
609 pyroserver.Quit() |
619 pyro_thread.join() |
610 pyro_thread.join() |
620 |
611 |
621 plcobj = runtime.GetPLCObjectSingleton() |
612 plcobj = runtime.GetPLCObjectSingleton() |