equal
deleted
inserted
replaced
28 from __future__ import print_function |
28 from __future__ import print_function |
29 import os |
29 import os |
30 import sys |
30 import sys |
31 import getopt |
31 import getopt |
32 import threading |
32 import threading |
33 from threading import Thread, currentThread, Semaphore |
33 from threading import Thread, currentThread, Semaphore, Lock |
34 import traceback |
34 import traceback |
35 import __builtin__ |
35 import __builtin__ |
|
36 import Pyro |
36 import Pyro.core as pyro |
37 import Pyro.core as pyro |
37 |
38 |
38 from runtime import PLCObject, ServicePublisher, MainWorker |
39 from runtime import PLCObject, ServicePublisher, MainWorker |
39 import util.paths as paths |
40 import util.paths as paths |
40 |
41 |
397 except Exception: |
398 except Exception: |
398 res = (None, sys.exc_info()) |
399 res = (None, sys.exc_info()) |
399 return res |
400 return res |
400 |
401 |
401 |
402 |
|
403 |
402 class Server(object): |
404 class Server(object): |
403 def __init__(self, servicename, ip_addr, port, |
405 def __init__(self, servicename, ip_addr, port, |
404 workdir, argv, |
406 workdir, argv, |
405 statuschange=None, evaluator=default_evaluator, |
407 statuschange=None, evaluator=default_evaluator, |
406 pyruntimevars=None): |
408 pyruntimevars=None): |
434 print(_("Publishing service on local network")) |
436 print(_("Publishing service on local network")) |
435 |
437 |
436 sys.stdout.flush() |
438 sys.stdout.flush() |
437 |
439 |
438 |
440 |
439 def PyroLoop(self): |
441 def PyroLoop(self, when_ready): |
440 while self.continueloop: |
442 while self.continueloop: |
|
443 Pyro.config.PYRO_MULTITHREADED = 0 |
441 pyro.initServer() |
444 pyro.initServer() |
442 self.daemon = pyro.Daemon(host=self.ip_addr, port=self.port) |
445 self.daemon = pyro.Daemon(host=self.ip_addr, port=self.port) |
443 |
446 |
444 # pyro never frees memory after connection close if no timeout set |
447 # pyro never frees memory after connection close if no timeout set |
445 # taking too small timeout value may cause |
448 # taking too small timeout value may cause |
450 |
453 |
451 if self._to_be_published(): |
454 if self._to_be_published(): |
452 self.servicepublisher = ServicePublisher.ServicePublisher() |
455 self.servicepublisher = ServicePublisher.ServicePublisher() |
453 self.servicepublisher.RegisterService(self.servicename, self.ip_addr, self.port) |
456 self.servicepublisher.RegisterService(self.servicename, self.ip_addr, self.port) |
454 |
457 |
|
458 when_ready() |
455 self.daemon.requestLoop() |
459 self.daemon.requestLoop() |
456 self.daemon.sock.close() |
460 self.daemon.sock.close() |
457 |
461 |
458 def Restart(self): |
462 def Restart(self): |
459 self._stop() |
463 self._stop() |
629 else: |
633 else: |
630 raise Exception(_("WAMP config is missing.")) |
634 raise Exception(_("WAMP config is missing.")) |
631 except Exception: |
635 except Exception: |
632 LogMessageAndException(_("WAMP client startup failed. ")) |
636 LogMessageAndException(_("WAMP client startup failed. ")) |
633 |
637 |
634 pyro_thread = Thread(target=pyroserver.PyroLoop) |
638 pyro_thread_started = Lock() |
|
639 pyro_thread_started.acquire() |
|
640 pyro_thread = Thread(target=pyroserver.PyroLoop, |
|
641 kwargs=dict(when_ready=pyro_thread_started.release)) |
635 pyro_thread.start() |
642 pyro_thread.start() |
636 |
643 |
|
644 # Wait for pyro thread to be effective |
|
645 pyro_thread_started.acquire() |
|
646 |
637 pyroserver.PrintServerInfo() |
647 pyroserver.PrintServerInfo() |
638 |
648 |
639 if havetwisted or havewx: |
649 if havetwisted or havewx: |
|
650 ui_thread_started = Lock() |
|
651 ui_thread_started.acquire() |
640 if havetwisted: |
652 if havetwisted: |
641 # reactor._installSignalHandlersAgain() |
653 # reactor._installSignalHandlersAgain() |
642 def ui_thread_target(): |
654 def ui_thread_target(): |
643 # FIXME: had to disable SignaHandlers install because |
655 # FIXME: had to disable SignaHandlers install because |
644 # signal not working in non-main thread |
656 # signal not working in non-main thread |
647 ui_thread_target = app.MainLoop |
659 ui_thread_target = app.MainLoop |
648 |
660 |
649 ui_thread = Thread(target = ui_thread_target) |
661 ui_thread = Thread(target = ui_thread_target) |
650 ui_thread.start() |
662 ui_thread.start() |
651 |
663 |
|
664 # This order ui loop to unblock main thread when ready. |
|
665 if havetwisted: |
|
666 reactor.callLater(0,ui_thread_started.release) |
|
667 else : |
|
668 wx.CallAfter(ui_thread_started.release) |
|
669 |
|
670 # Wait for ui thread to be effective |
|
671 ui_thread_started.acquire() |
|
672 print("UI thread started successfully.") |
|
673 |
652 try: |
674 try: |
653 MainWorker.runloop(pyroserver.AutoLoad) |
675 MainWorker.runloop(pyroserver.AutoLoad) |
654 except KeyboardInterrupt: |
676 except KeyboardInterrupt: |
655 pass |
677 pass |
656 |
678 |