runtime/Worker.py
author Edouard Tisserant <edouard.tisserant@gmail.com>
Tue, 15 Nov 2022 20:43:39 +0100
branchwxPython4
changeset 3677 6d9040e07c32
parent 3642 cd3d15e8ef42
child 3750 f62625418bff
permissions -rw-r--r--
OPC-UA: only support the encryption policy selected in config.

By default open62541 client accepts all supported policies, but in makes problem
when negociating with some servers while most clients seems to only support
one policy at a time.
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     1
#!/usr/bin/env python
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     3
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     4
# This file is part of Beremiz runtime.
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     5
#
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     6
# Copyright (C) 2018: Edouard TISSERANT
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     7
#
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     8
# See COPYING.Runtime file for copyrights details.
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     9
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    10
from __future__ import absolute_import
2307
c44692b53736 Show more exceptions on stdout, particularly those that are raised by AutoLoad (first item in Main Thread worker)
Edouard Tisserant
parents: 2271
diff changeset
    11
import sys
3584
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
    12
from threading import Lock, Condition, Thread
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
    13
2492
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2486
diff changeset
    14
import six
2537
eb4a4cc41914 Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2536
diff changeset
    15
from six.moves import _thread
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    16
2309
d8fb90a2e11f Please pylint and pep8
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2307
diff changeset
    17
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    18
class job(object):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    19
    """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    20
    job to be executed by a worker
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    21
    """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    22
    def __init__(self, call, *args, **kwargs):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    23
        self.job = (call, args, kwargs)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    24
        self.result = None
2604
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
    25
        self.success = None
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    26
        self.exc_info = None
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    27
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    28
    def do(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    29
        """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    30
        do the job by executing the call, and deal with exceptions
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    31
        """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    32
        try:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    33
            call, args, kwargs = self.job
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    34
            self.result = call(*args, **kwargs)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    35
            self.success = True
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    36
        except Exception:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    37
            self.success = False
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    38
            self.exc_info = sys.exc_info()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    39
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    40
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    41
class worker(object):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    42
    """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    43
    serialize main thread load/unload of PLC shared objects
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    44
    """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    45
    def __init__(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    46
        # Only one job at a time
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    47
        self._finish = False
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    48
        self._threadID = None
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    49
        self.mutex = Lock()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    50
        self.todo = Condition(self.mutex)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    51
        self.done = Condition(self.mutex)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    52
        self.free = Condition(self.mutex)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    53
        self.job = None
2611
a1bf03277cec Fixed typo leading to some exception in some rare corner cases in worker.py
Edouard Tisserant
parents: 2604
diff changeset
    54
        self.enabled = False
3642
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
    55
        self.stopper = None
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
    56
        self.own_thread = None
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    57
2536
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    58
    def reraise(self, job):
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    59
        """
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    60
        reraise exception happend in a job
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    61
        @param job: job where original exception happend
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    62
        """
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    63
        exc_type = job.exc_info[0]
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    64
        exc_value = job.exc_info[1]
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    65
        exc_traceback = job.exc_info[2]
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    66
        six.reraise(exc_type, exc_value, exc_traceback)
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    67
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    68
    def runloop(self, *args, **kwargs):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    69
        """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    70
        meant to be called by worker thread (blocking)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    71
        """
2537
eb4a4cc41914 Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2536
diff changeset
    72
        self._threadID = _thread.get_ident()
2467
fce6ab7ae156 Enure that autostart blocks other @RunInMain PLCObject methods, and _unblocks_ them once autostart is done...
Edouard Tisserant
parents: 2463
diff changeset
    73
        self.mutex.acquire()
2604
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
    74
        self.enabled = True
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    75
        if args or kwargs:
2307
c44692b53736 Show more exceptions on stdout, particularly those that are raised by AutoLoad (first item in Main Thread worker)
Edouard Tisserant
parents: 2271
diff changeset
    76
            _job = job(*args, **kwargs)
c44692b53736 Show more exceptions on stdout, particularly those that are raised by AutoLoad (first item in Main Thread worker)
Edouard Tisserant
parents: 2271
diff changeset
    77
            _job.do()
2604
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
    78
            # _job.success can't be None after do()
2536
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    79
            if not _job.success:
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
    80
                self.reraise(_job)
2486
44c2a4e2b84d Fixed deadlock in runtime's Worker. Was discovered while using WAMP and PYRO simultaneously.
Edouard Tisserant
parents: 2467
diff changeset
    81
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    82
        while not self._finish:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    83
            self.todo.wait()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    84
            if self.job is not None:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    85
                self.job.do()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    86
                self.done.notify()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    87
            else:
2486
44c2a4e2b84d Fixed deadlock in runtime's Worker. Was discovered while using WAMP and PYRO simultaneously.
Edouard Tisserant
parents: 2467
diff changeset
    88
                break
44c2a4e2b84d Fixed deadlock in runtime's Worker. Was discovered while using WAMP and PYRO simultaneously.
Edouard Tisserant
parents: 2467
diff changeset
    89
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    90
        self.mutex.release()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    91
3642
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
    92
    def interleave(self, waker, stopper, *args, **kwargs):
3584
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
    93
        """
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
    94
        as for twisted reactor's interleave, it passes all jobs to waker func
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
    95
        additionaly, it creates a new thread to wait for new job.
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
    96
        """
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
    97
        self.feed = Condition(self.mutex)
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
    98
        self._threadID = _thread.get_ident()
3642
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
    99
        self.stopper = stopper
3584
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   100
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   101
        def wakerfeedingloop():
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   102
            self.mutex.acquire()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   103
            self.enabled = True
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   104
            if args or kwargs:
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   105
                def first_job_todo():
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   106
                    _job = job(*args, **kwargs)
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   107
                    _job.do()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   108
                    if not _job.success:
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   109
                        self.reraise(_job)
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   110
                    self.mutex.acquire()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   111
                    self.feed.notify()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   112
                    self.mutex.release()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   113
                waker(first_job_todo)
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   114
                self.feed.wait()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   115
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   116
            while not self._finish:
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   117
                self.todo.wait()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   118
                def job_todo():
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   119
                    self.mutex.acquire()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   120
                    if self.job is not None:
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   121
                        self.job.do()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   122
                        self.feed.notify()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   123
                        self.done.notify()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   124
                    self.mutex.release()
3642
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
   125
                if self._finish:
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
   126
                    break
3584
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   127
                waker(job_todo)
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   128
                self.feed.wait()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   129
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   130
            self.mutex.release()
3585
efdefbad49eb runtime: fix bugs introduced in previous commit, and refactor some code
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3584
diff changeset
   131
        self.own_thread = Thread(target = wakerfeedingloop)
efdefbad49eb runtime: fix bugs introduced in previous commit, and refactor some code
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3584
diff changeset
   132
        self.own_thread.start()
3584
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   133
3585
efdefbad49eb runtime: fix bugs introduced in previous commit, and refactor some code
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3584
diff changeset
   134
    def stop(self):
3584
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   135
        """
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   136
        !interleave
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   137
        """
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   138
        self.mutex.acquire()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   139
        self._finish = True
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   140
        self.enabled = False
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   141
        self.job = None
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   142
        self.todo.notify()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   143
        self.done.notify()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   144
        self.mutex.release()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   145
        self.own_thread.join()
8a54fd58a552 Runtime: wx.app.mainLoop and twisted reactor now share main thread with runtime.Worker.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2611
diff changeset
   146
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   147
    def call(self, *args, **kwargs):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   148
        """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   149
        creates a job, execute it in worker thread, and deliver result.
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   150
        if job execution raise exception, re-raise same exception
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   151
        meant to be called by non-worker threads, but this is accepted.
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   152
        blocking until job done
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   153
        """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   154
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   155
        _job = job(*args, **kwargs)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   156
2537
eb4a4cc41914 Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2536
diff changeset
   157
        if self._threadID == _thread.get_ident():
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   158
            # if caller is worker thread execute immediately
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   159
            _job.do()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   160
        else:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   161
            # otherwise notify and wait for completion
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   162
            self.mutex.acquire()
2604
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
   163
            if not self.enabled:
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
   164
                self.mutex.release()
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
   165
                raise EOFError("Worker is disabled")
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   166
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   167
            while self.job is not None:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   168
                self.free.wait()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   169
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   170
            self.job = _job
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   171
            self.todo.notify()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   172
            self.done.wait()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   173
            self.job = None
2486
44c2a4e2b84d Fixed deadlock in runtime's Worker. Was discovered while using WAMP and PYRO simultaneously.
Edouard Tisserant
parents: 2467
diff changeset
   174
            self.free.notify()
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   175
            self.mutex.release()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   176
2604
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
   177
        if _job.success is None:
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
   178
            raise EOFError("Worker job was interrupted")
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
   179
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   180
        if _job.success:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   181
            return _job.result
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   182
        else:
2536
2747d6e72eb8 Fix invalid python3 syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 2492
diff changeset
   183
            self.reraise(_job)
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   184
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   185
    def quit(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   186
        """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   187
        unblocks main thread, and terminate execution of runloop()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   188
        """
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   189
        # mark queue
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   190
        self._finish = True
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   191
        self.mutex.acquire()
2604
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
   192
        self.enabled = False
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   193
        self.job = None
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   194
        self.todo.notify()
2604
c8a25a3a7f8b Runtime worker : unblock the last waiting job and prevent any new job to wait when Main Worker is being shut down.
Edouard Tisserant
parents: 2537
diff changeset
   195
        self.done.notify()
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   196
        self.mutex.release()
3642
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
   197
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
   198
    def finish(self):
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
   199
        if self.own_thread is None:
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
   200
            self.quit()
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
   201
        if self.stopper is not None:
cd3d15e8ef42 Runtime: fix PLC not terminating when being Repaired (i.e purged).
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3585
diff changeset
   202
            self.stopper()