runtime/PLCObject.py
author Andrey Skvortsov <andrej.skvortzov@gmail.com>
Wed, 23 May 2018 11:48:34 +0300
changeset 2015 4eeefc6a13fd
parent 1997 d9e8fb47340f
child 2270 d9175daf6522
child 2416 1ca207782dde
permissions -rwxr-xr-x
Fix codestyle
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     1
#!/usr/bin/env python
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     2
# -*- coding: utf-8 -*-
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     3
1667
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
     4
# This file is part of Beremiz runtime.
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     5
#
1571
486f94a8032c fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1570
diff changeset
     6
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     7
#
1667
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
     8
# See COPYING.Runtime file for copyrights details.
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     9
#
1667
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    10
# This library is free software; you can redistribute it and/or
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    11
# modify it under the terms of the GNU Lesser General Public
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    12
# License as published by the Free Software Foundation; either
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    13
# version 2.1 of the License, or (at your option) any later version.
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    14
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    15
# This library is distributed in the hope that it will be useful,
1571
486f94a8032c fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1570
diff changeset
    16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
1667
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    18
# Lesser General Public License for more details.
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    19
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    20
# You should have received a copy of the GNU Lesser General Public
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    21
# License along with this library; if not, write to the Free Software
cefc9219bb48 runtime is licensed under LGPLv2.1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1571
diff changeset
    22
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    23
1832
0f1081928d65 fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1831
diff changeset
    24
1881
091005ec69c4 fix pylint py3k conversion warning: "(no-absolute-import) import missing `from __future__ import absolute_import`"
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1878
diff changeset
    25
from __future__ import absolute_import
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    26
import thread
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    27
from threading import Thread, Lock, Semaphore, Event, Condition
1732
94ffe74e6895 clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1730
diff changeset
    28
import ctypes
94ffe74e6895 clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1730
diff changeset
    29
import os
94ffe74e6895 clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1730
diff changeset
    30
import sys
1783
3311eea28d56 clean-up: fix PEP8 E402 module level import not at top of file
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1780
diff changeset
    31
import traceback
1832
0f1081928d65 fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1831
diff changeset
    32
from time import time
1956
2b90514edfbf Another attempt to make BitBuket's version of pylint happy.
Edouard Tisserant
parents: 1955
diff changeset
    33
import _ctypes  # pylint: disable=wrong-import-order
1832
0f1081928d65 fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1831
diff changeset
    34
import Pyro.core as pyro
0f1081928d65 fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1831
diff changeset
    35
1902
2b7e2db31d81 Clarify licensing, and packaging of runtime only files :
Edouard Tisserant
parents: 1881
diff changeset
    36
from runtime.typemapping import TypeTranslator
2b7e2db31d81 Clarify licensing, and packaging of runtime only files :
Edouard Tisserant
parents: 1881
diff changeset
    37
from runtime.loglevels import LogLevelsDefault, LogLevelsCount
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
    38
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    39
if os.name in ("nt", "ce"):
1919
ccea0fa6ea91 Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents: 1906
diff changeset
    40
    dlopen = _ctypes.LoadLibrary
ccea0fa6ea91 Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents: 1906
diff changeset
    41
    dlclose = _ctypes.FreeLibrary
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    42
elif os.name == "posix":
1919
ccea0fa6ea91 Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents: 1906
diff changeset
    43
    dlopen = _ctypes.dlopen
ccea0fa6ea91 Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents: 1906
diff changeset
    44
    dlclose = _ctypes.dlclose
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    45
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1734
diff changeset
    46
699
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    47
def get_last_traceback(tb):
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    48
    while tb.tb_next:
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    49
        tb = tb.tb_next
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
    50
    return tb
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    51
1749
d73b64672238 clean-up: fix PEP8 E305 expected 2 blank lines after class or function definition
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1745
diff changeset
    52
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
    53
lib_ext = {
1878
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
    54
    "linux2": ".so",
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
    55
    "win32":  ".dll",
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
    56
}.get(sys.platform, "")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    57
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1734
diff changeset
    58
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    59
def PLCprint(message):
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    60
    sys.stdout.write("PLCobject : "+message+"\n")
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    61
    sys.stdout.flush()
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    62
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1734
diff changeset
    63
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    64
class job(object):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    65
    """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    66
    job to be executed by a worker
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    67
    """
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    68
    def __init__(self, call, *args, **kwargs):
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    69
        self.job = (call, args, kwargs)
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    70
        self.result = None
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    71
        self.success = False
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    72
        self.exc_info = None
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    73
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    74
    def do(self):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    75
        """
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    76
        do the job by executing the call, and deal with exceptions
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    77
        """
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    78
        try:
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    79
            call, args, kwargs = self.job
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
    80
            self.result = call(*args, **kwargs)
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    81
            self.success = True
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    82
        except Exception:
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    83
            self.success = False
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    84
            self.exc_info = sys.exc_info()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    85
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    86
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    87
class worker(object):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    88
    """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    89
    serialize main thread load/unload of PLC shared objects
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    90
    """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    91
    def __init__(self):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    92
        # Only one job at a time
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    93
        self._finish = False
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    94
        self._threadID = None
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    95
        self.mutex = Lock()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    96
        self.todo = Condition(self.mutex)
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    97
        self.done = Condition(self.mutex)
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
    98
        self.free = Condition(self.mutex)
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
    99
        self.job = None
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   100
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   101
    def runloop(self, *args, **kwargs):
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   102
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   103
        meant to be called by worker thread (blocking)
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   104
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   105
        self._threadID = thread.get_ident()
1988
19ca02e8074f PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents: 1987
diff changeset
   106
        if args or kwargs:
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   107
            job(*args, **kwargs).do()
1988
19ca02e8074f PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents: 1987
diff changeset
   108
            # result is ignored
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   109
        self.mutex.acquire()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   110
        while not self._finish:
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   111
            self.todo.wait()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   112
            if self.job is not None:
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   113
                self.job.do()
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   114
                self.done.notify()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   115
            else:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   116
                self.free.notify()
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   117
        self.mutex.release()
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   118
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   119
    def call(self, *args, **kwargs):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   120
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   121
        creates a job, execute it in worker thread, and deliver result.
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   122
        if job execution raise exception, re-raise same exception
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   123
        meant to be called by non-worker threads, but this is accepted.
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   124
        blocking until job done
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   125
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   126
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   127
        _job = job(*args, **kwargs)
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   128
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   129
        if self._threadID == thread.get_ident() or self._threadID is None:
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   130
            # if caller is worker thread execute immediately
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   131
            _job.do()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   132
        else:
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   133
            # otherwise notify and wait for completion
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   134
            self.mutex.acquire()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   135
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   136
            while self.job is not None:
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   137
                self.free.wait()
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   138
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   139
            self.job = _job
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   140
            self.todo.notify()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   141
            self.done.wait()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   142
            _job = self.job
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   143
            self.job = None
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   144
            self.mutex.release()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   145
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   146
        if _job.success:
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   147
            return _job.result
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   148
        else:
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   149
            raise _job.exc_info[0], _job.exc_info[1], _job.exc_info[2]
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   150
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   151
    def quit(self):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   152
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   153
        unblocks main thread, and terminate execution of runloop()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   154
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   155
        # mark queue
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   156
        self._finish = True
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   157
        self.mutex.acquire()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   158
        self.job = None
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   159
        self.todo.notify()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   160
        self.mutex.release()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   161
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   162
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   163
MainWorker = worker()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   164
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   165
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   166
def RunInMain(func):
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   167
    def func_wrapper(*args, **kwargs):
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   168
        return MainWorker.call(func, *args, **kwargs)
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   169
    return func_wrapper
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   170
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   171
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   172
class PLCObject(pyro.ObjBase):
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   173
    def __init__(self, server):
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   174
        pyro.ObjBase.__init__(self)
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   175
        self.evaluator = server.evaluator
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   176
        self.argv = [server.workdir] + server.argv  # force argv[0] to be "path" to exec...
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   177
        self.workingdir = server.workdir
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   178
        self.PLCStatus = "Empty"
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   179
        self.PLClibraryHandle = None
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   180
        self.PLClibraryLock = Lock()
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   181
        self.DummyIteratorLock = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   182
        # Creates fake C funcs proxies
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   183
        self._InitPLCStubCalls()
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   184
        self.daemon = server.daemon
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   185
        self.statuschange = server.statuschange
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
   186
        self.hmi_frame = None
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   187
        self.pyruntimevars = server.pyruntimevars
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   188
        self._loading_error = None
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   189
        self.python_runtime_vars = None
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   190
        self.TraceThread = None
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   191
        self.TraceLock = Lock()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   192
        self.Traces = []
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   193
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   194
    # First task of worker -> no @RunInMain
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   195
    def AutoLoad(self):
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   196
        # Get the last transfered PLC
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   197
        try:
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   198
            self.CurrentPLCFilename = open(
1878
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
   199
                self._GetMD5FileName(),
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
   200
                "r").read().strip() + lib_ext
1570
0925da818853 fix PLC autostart option for Beremiz_service.py
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1463
diff changeset
   201
            if self.LoadPLC():
0925da818853 fix PLC autostart option for Beremiz_service.py
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1463
diff changeset
   202
                self.PLCStatus = "Stopped"
1846
14b40afccd69 remove unused variables found by pylint
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1832
diff changeset
   203
        except Exception:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   204
            self.PLCStatus = "Empty"
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   205
            self.CurrentPLCFilename = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   206
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   207
    def StatusChange(self):
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   208
        if self.statuschange is not None:
1438
19ebe96b41c0 Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents: 1435
diff changeset
   209
            for callee in self.statuschange:
19ebe96b41c0 Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents: 1435
diff changeset
   210
                callee(self.PLCStatus)
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   211
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   212
    @RunInMain
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   213
    def LogMessage(self, *args):
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   214
        if len(args) == 2:
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   215
            level, msg = args
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   216
        else:
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   217
            level = LogLevelsDefault
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   218
            msg, = args
1906
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   219
        PLCprint(msg)
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   220
        if self._LogMessage is not None:
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   221
            return self._LogMessage(level, msg, len(msg))
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   222
        return None
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   223
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   224
    @RunInMain
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   225
    def ResetLogCount(self):
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   226
        if self._ResetLogCount is not None:
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   227
            self._ResetLogCount()
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   228
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   229
    # used internaly
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   230
    def GetLogCount(self, level):
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   231
        if self._GetLogCount is not None:
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   232
            return int(self._GetLogCount(level))
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   233
        elif self._loading_error is not None and level == 0:
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   234
            return 1
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   235
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   236
    @RunInMain
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   237
    def GetLogMessage(self, level, msgid):
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   238
        tick = ctypes.c_uint32()
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   239
        tv_sec = ctypes.c_uint32()
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   240
        tv_nsec = ctypes.c_uint32()
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   241
        if self._GetLogMessage is not None:
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   242
            maxsz = len(self._log_read_buffer)-1
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   243
            sz = self._GetLogMessage(level, msgid,
1768
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   244
                                     self._log_read_buffer, maxsz,
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   245
                                     ctypes.byref(tick),
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   246
                                     ctypes.byref(tv_sec),
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   247
                                     ctypes.byref(tv_nsec))
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   248
            if sz and sz <= maxsz:
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   249
                self._log_read_buffer[sz] = '\x00'
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   250
                return self._log_read_buffer.value, tick.value, tv_sec.value, tv_nsec.value
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   251
        elif self._loading_error is not None and level == 0:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   252
            return self._loading_error, 0, 0, 0
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   253
        return None
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   254
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   255
    def _GetMD5FileName(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   256
        return os.path.join(self.workingdir, "lasttransferedPLC.md5")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   257
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   258
    def _GetLibFileName(self):
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   259
        return os.path.join(self.workingdir, self.CurrentPLCFilename)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   260
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   261
    def _LoadPLC(self):
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   262
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   263
        Load PLC library
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   264
        Declare all functions, arguments and return values
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   265
        """
1457
ff7cfce737ca Added PLCID variable accessible from C side, set with binarie's MD5. Added retain init and cleanup calls. Extended tests/python to test PLCID
Edouard Tisserant
parents: 1447
diff changeset
   266
        md5 = open(self._GetMD5FileName(), "r").read()
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   267
        self.PLClibraryLock.acquire()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   268
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   269
            self._PLClibraryHandle = dlopen(self._GetLibFileName())
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   270
            self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   271
1463
de311ffe3961 Changed runtime's global PLCID to PLC_ID, working around redefinition in windoze' headers.
Edouard Tisserant
parents: 1457
diff changeset
   272
            self.PLC_ID = ctypes.c_char_p.in_dll(self.PLClibraryHandle, "PLC_ID")
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   273
            if len(md5) == 32:
1730
64d8f52bc8c8 clean-up for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1667
diff changeset
   274
                self.PLC_ID.value = md5
1457
ff7cfce737ca Added PLCID variable accessible from C side, set with binarie's MD5. Added retain init and cleanup calls. Extended tests/python to test PLCID
Edouard Tisserant
parents: 1447
diff changeset
   275
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   276
            self._startPLC = self.PLClibraryHandle.startPLC
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   277
            self._startPLC.restype = ctypes.c_int
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   278
            self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   279
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   280
            self._stopPLC_real = self.PLClibraryHandle.stopPLC
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   281
            self._stopPLC_real.restype = None
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   282
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   283
            self._PythonIterator = getattr(self.PLClibraryHandle, "PythonIterator", None)
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   284
            if self._PythonIterator is not None:
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   285
                self._PythonIterator.restype = ctypes.c_char_p
851
666f5bdad301 Added FBID variable to PY_EVAL evaluation context. FBID does identify uniquely py_eval block instance triggering execution
Edouard Tisserant
parents: 798
diff changeset
   286
                self._PythonIterator.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_void_p)]
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   287
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   288
                self._stopPLC = self._stopPLC_real
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   289
            else:
717
1c23952dbde1 refactoring
Edouard Tisserant
parents: 699
diff changeset
   290
                # If python confnode is not enabled, we reuse _PythonIterator
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   291
                # as a call that block pythonthread until StopPLC
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   292
                self.PlcStopping = Event()
1750
acf02488f37f clean-up: fix PEP8 E306 expected 1 blank line before a nested definition, found X
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1749
diff changeset
   293
868
7e5da4962bea Fix bug of PythonIterator signature in PLCObject when not using PythonLibrary
Edouard Tisserant
parents: 867
diff changeset
   294
                def PythonIterator(res, blkid):
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   295
                    self.PlcStopping.clear()
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   296
                    self.PlcStopping.wait()
366
cd90e4c10261 Move python evaluator to create a python plugin containing any related python module
laurent
parents: 365
diff changeset
   297
                    return None
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   298
                self._PythonIterator = PythonIterator
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   299
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   300
                def __StopPLC():
455
e050ef5bd285 Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents: 450
diff changeset
   301
                    self._stopPLC_real()
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   302
                    self.PlcStopping.set()
483
bc26c42d2eec fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents: 479
diff changeset
   303
                self._stopPLC = __StopPLC
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   304
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   305
            self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   306
            self._ResetDebugVariables.restype = None
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   307
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   308
            self._RegisterDebugVariable = self.PLClibraryHandle.RegisterDebugVariable
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   309
            self._RegisterDebugVariable.restype = None
477
f66a092b6e74 Arbitrary variable forcing
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 467
diff changeset
   310
            self._RegisterDebugVariable.argtypes = [ctypes.c_int, ctypes.c_void_p]
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   311
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   312
            self._FreeDebugData = self.PLClibraryHandle.FreeDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   313
            self._FreeDebugData.restype = None
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   314
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   315
            self._GetDebugData = self.PLClibraryHandle.GetDebugData
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   316
            self._GetDebugData.restype = ctypes.c_int
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   317
            self._GetDebugData.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_void_p)]
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   318
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   319
            self._suspendDebug = self.PLClibraryHandle.suspendDebug
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   320
            self._suspendDebug.restype = ctypes.c_int
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   321
            self._suspendDebug.argtypes = [ctypes.c_int]
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   322
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   323
            self._resumeDebug = self.PLClibraryHandle.resumeDebug
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   324
            self._resumeDebug.restype = None
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   325
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   326
            self._ResetLogCount = self.PLClibraryHandle.ResetLogCount
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   327
            self._ResetLogCount.restype = None
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   328
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   329
            self._GetLogCount = self.PLClibraryHandle.GetLogCount
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   330
            self._GetLogCount.restype = ctypes.c_uint32
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   331
            self._GetLogCount.argtypes = [ctypes.c_uint8]
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   332
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   333
            self._LogMessage = self.PLClibraryHandle.LogMessage
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   334
            self._LogMessage.restype = ctypes.c_int
971
c4550f76ae05 reverted PLCObject.py. ctypes.POINTER(ctypes.c_uint8) != string
Edouard Tisserant
parents: 969
diff changeset
   335
            self._LogMessage.argtypes = [ctypes.c_uint8, ctypes.c_char_p, ctypes.c_uint32]
1093
b5f78cff4459 Added support for resetting log messages
Laurent Bessard
parents: 1075
diff changeset
   336
1760
ed2e2afb9573 clean-up: fix PEP8 E262 inline comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1750
diff changeset
   337
            self._log_read_buffer = ctypes.create_string_buffer(1 << 14)  # 16K
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   338
            self._GetLogMessage = self.PLClibraryHandle.GetLogMessage
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   339
            self._GetLogMessage.restype = ctypes.c_uint32
921
a8db48ec2c31 Added log messages time-stamping
Edouard Tisserant
parents: 917
diff changeset
   340
            self._GetLogMessage.argtypes = [ctypes.c_uint8, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)]
911
ffa24427396a Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents: 906
diff changeset
   341
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   342
            self._loading_error = None
1035
0f905e027d18 Better mdns resolution failure signaling, added fixed bug whith runtime autostart
Edouard Tisserant
parents: 1027
diff changeset
   343
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   344
        except Exception:
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   345
            self._loading_error = traceback.format_exc()
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   346
            PLCprint(self._loading_error)
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   347
            return False
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   348
        finally:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   349
            self.PLClibraryLock.release()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   350
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   351
        return True
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   352
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   353
    @RunInMain
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   354
    def LoadPLC(self):
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   355
        res = self._LoadPLC()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   356
        if res:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   357
            self.PythonRuntimeInit()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   358
        else:
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   359
            self._FreePLC()
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   360
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   361
        return res
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   362
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   363
    @RunInMain
1045
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   364
    def UnLoadPLC(self):
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   365
        self.PythonRuntimeCleanup()
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   366
        self._FreePLC()
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   367
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   368
    def _InitPLCStubCalls(self):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   369
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   370
        create dummy C func proxies
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   371
        """
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   372
        self._startPLC = lambda x, y: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   373
        self._stopPLC = lambda: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   374
        self._ResetDebugVariables = lambda: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   375
        self._RegisterDebugVariable = lambda x, y: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   376
        self._IterDebugData = lambda x, y: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   377
        self._FreeDebugData = lambda: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   378
        self._GetDebugData = lambda: -1
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   379
        self._suspendDebug = lambda x: -1
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   380
        self._resumeDebug = lambda: None
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   381
        self._PythonIterator = lambda: ""
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   382
        self._GetLogCount = None
1906
60edd0c901f1 Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents: 1902
diff changeset
   383
        self._LogMessage = None
914
94436558f0ce More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
Edouard Tisserant
parents: 911
diff changeset
   384
        self._GetLogMessage = None
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   385
        self._PLClibraryHandle = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   386
        self.PLClibraryHandle = None
1984
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   387
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   388
    def _FreePLC(self):
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   389
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   390
        Unload PLC library.
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   391
        This is also called by __init__ to create dummy C func proxies
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   392
        """
081265cda5b1 Intermediate state while implementing runtime worker to ensure that PLCObject Load and Unload methods always run main thread.
Edouard Tisserant
parents: 1983
diff changeset
   393
        self.PLClibraryLock.acquire()
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   394
        try:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   395
            # Unload library explicitely
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   396
            if getattr(self, "_PLClibraryHandle", None) is not None:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   397
                dlclose(self._PLClibraryHandle)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   398
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   399
            # Forget all refs to library
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   400
            self._InitPLCStubCalls()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   401
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   402
        finally:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   403
            self.PLClibraryLock.release()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   404
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   405
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   406
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   407
    def PythonRuntimeCall(self, methodname):
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   408
        """
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   409
        Calls init, start, stop or cleanup method provided by
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   410
        runtime python files, loaded when new PLC uploaded
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   411
        """
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   412
        for method in self.python_runtime_vars.get("_runtime_%s" % methodname, []):
1847
6198190bc121 explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1846
diff changeset
   413
            _res, exp = self.evaluator(method)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   414
            if exp is not None:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   415
                self.LogMessage(0, '\n'.join(traceback.format_exception(*exp)))
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   416
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   417
    # used internaly
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   418
    def PythonRuntimeInit(self):
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   419
        MethodNames = ["init", "start", "stop", "cleanup"]
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   420
        self.python_runtime_vars = globals().copy()
1438
19ebe96b41c0 Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents: 1435
diff changeset
   421
        self.python_runtime_vars.update(self.pyruntimevars)
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   422
        parent = self
1438
19ebe96b41c0 Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents: 1435
diff changeset
   423
1831
56b48961cc68 fix (old-style-class) Old-style class defined error for most parts of
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1783
diff changeset
   424
        class PLCSafeGlobals(object):
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   425
            def __getattr__(self, name):
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   426
                try:
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   427
                    t = parent.python_runtime_vars["_"+name+"_ctype"]
1156
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   428
                except KeyError:
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   429
                    raise KeyError("Try to get unknown shared global variable : %s" % name)
1156
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   430
                v = t()
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   431
                parent.python_runtime_vars["_PySafeGetPLCGlob_"+name](ctypes.byref(v))
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   432
                return parent.python_runtime_vars["_"+name+"_unpack"](v)
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   433
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   434
            def __setattr__(self, name, value):
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   435
                try:
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   436
                    t = parent.python_runtime_vars["_"+name+"_ctype"]
1156
9708ed2a4ac2 Added more clear error message in case of access to non declared PLC global from python code
Edouard Tisserant
parents: 1145
diff changeset
   437
                except KeyError:
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   438
                    raise KeyError("Try to set unknown shared global variable : %s" % name)
1868
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   439
                v = parent.python_runtime_vars["_"+name+"_pack"](t, value)
616c3f4bcbcb fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1850
diff changeset
   440
                parent.python_runtime_vars["_PySafeSetPLCGlob_"+name](ctypes.byref(v))
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   441
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   442
        self.python_runtime_vars.update({
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   443
            "PLCGlobals":     PLCSafeGlobals(),
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   444
            "WorkingDir":     self.workingdir,
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   445
            "PLCObject":      self,
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   446
            "PLCBinary":      self.PLClibraryHandle,
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   447
            "PLCGlobalsDesc": []})
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   448
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   449
        for methodname in MethodNames:
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   450
            self.python_runtime_vars["_runtime_%s" % methodname] = []
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   451
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   452
        try:
1447
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   453
            filenames = os.listdir(self.workingdir)
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   454
            filenames.sort()
d6b878525ceb Fixed systematically loading PLC binary at startup even without -a parameter. Extended py_ext extensions instances variable description (PLCGlobalsDesc). Now contains list of variables organizd by extension, with extension name
Edouard Tisserant
parents: 1442
diff changeset
   455
            for filename in filenames:
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   456
                name, ext = os.path.splitext(filename)
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   457
                if name.upper().startswith("RUNTIME") and ext.upper() == ".PY":
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   458
                    execfile(os.path.join(self.workingdir, filename), self.python_runtime_vars)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   459
                    for methodname in MethodNames:
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   460
                        method = self.python_runtime_vars.get("_%s_%s" % (name, methodname), None)
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   461
                        if method is not None:
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   462
                            self.python_runtime_vars["_runtime_%s" % methodname].append(method)
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   463
        except Exception:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   464
            self.LogMessage(0, traceback.format_exc())
972
659198075ce4 Redirect PyEval exceptions to logging
Edouard Tisserant
parents: 971
diff changeset
   465
            raise
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   466
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   467
        self.PythonRuntimeCall("init")
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   468
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   469
    # used internaly
1014
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   470
    def PythonRuntimeCleanup(self):
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   471
        if self.python_runtime_vars is not None:
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   472
            self.PythonRuntimeCall("cleanup")
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   473
e2f7d6c95db0 Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents: 1011
diff changeset
   474
        self.python_runtime_vars = None
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   475
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   476
    def PythonThreadProc(self):
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   477
        self.StartSem.release()
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   478
        res, cmd, blkid = "None", "None", ctypes.c_void_p()
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   479
        compile_cache = {}
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   480
        while True:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   481
            cmd = self._PythonIterator(res, blkid)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   482
            FBID = blkid.value
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   483
            if cmd is None:
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   484
                break
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   485
            try:
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   486
                self.python_runtime_vars["FBID"] = FBID
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   487
                ccmd, AST = compile_cache.get(FBID, (None, None))
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   488
                if ccmd is None or ccmd != cmd:
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   489
                    AST = compile(cmd, '<plc>', 'eval')
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   490
                    compile_cache[FBID] = (cmd, AST)
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   491
                result, exp = self.evaluator(eval, AST, self.python_runtime_vars)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   492
                if exp is not None:
1052
fa7c5034c1d2 Better display of Python exceptions from Py_Eval
Edouard Tisserant
parents: 1051
diff changeset
   493
                    res = "#EXCEPTION : "+str(exp[1])
1768
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   494
                    self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (
691083b5682a clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1767
diff changeset
   495
                        FBID, cmd, '\n'.join(traceback.format_exception(*exp))))
867
06495975e8a4 Added caching for python eval (avoid compiling when same code called, but still execute). Cleaned up some evaluator related code.
Edouard Tisserant
parents: 851
diff changeset
   496
                else:
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   497
                    res = str(result)
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   498
                self.python_runtime_vars["FBID"] = None
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   499
            except Exception, e:
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   500
                res = "#EXCEPTION : "+str(e)
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   501
                self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (FBID, cmd, str(e)))
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   502
1988
19ca02e8074f PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents: 1987
diff changeset
   503
    @RunInMain
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   504
    def StartPLC(self):
465
67d32a91d70b Fixes in debug + reconnect to running PLC
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 462
diff changeset
   505
        if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   506
            c_argv = ctypes.c_char_p * len(self.argv)
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   507
            res = self._startPLC(len(self.argv), c_argv(*self.argv))
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   508
            if res == 0:
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   509
                self.PLCStatus = "Started"
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   510
                self.StatusChange()
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   511
                self.PythonRuntimeCall("start")
1742
92932cd370a4 clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1741
diff changeset
   512
                self.StartSem = Semaphore(0)
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   513
                self.PythonThread = Thread(target=self.PythonThreadProc)
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   514
                self.PythonThread.start()
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   515
                self.StartSem.acquire()
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   516
                self.LogMessage("PLC started")
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   517
            else:
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   518
                self.LogMessage(0, _("Problem starting PLC : error %d" % res))
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   519
                self.PLCStatus = "Broken"
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   520
                self.StatusChange()
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   521
1988
19ca02e8074f PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents: 1987
diff changeset
   522
    @RunInMain
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   523
    def StopPLC(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   524
        if self.PLCStatus == "Started":
917
401e44bae7c0 Now logging have 4 levels
Edouard Tisserant
parents: 914
diff changeset
   525
            self.LogMessage("PLC stopped")
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   526
            self._stopPLC()
798
0d2423f283a6 Fix bug segmentation fault while cleanup extensions
laurent
parents: 795
diff changeset
   527
            self.PythonThread.join()
1442
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   528
            self.PLCStatus = "Stopped"
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   529
            self.StatusChange()
ad9a7853dea2 Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents: 1440
diff changeset
   530
            self.PythonRuntimeCall("stop")
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   531
            if self.TraceThread is not None:
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   532
                self.TraceThread.join()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   533
                self.TraceThread = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   534
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   535
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   536
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   537
    @RunInMain
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   538
    def GetPLCstatus(self):
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   539
        return self.PLCStatus, map(self.GetLogCount, xrange(LogLevelsCount))
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   540
1988
19ca02e8074f PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents: 1987
diff changeset
   541
    @RunInMain
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   542
    def NewPLC(self, md5sum, data, extrafiles):
393
af20e07e53c5 Remove dirtylibs test while freeing plc libs in PLCObject.py
laurent
parents: 368
diff changeset
   543
        if self.PLCStatus in ["Stopped", "Empty", "Broken"]:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   544
            NewFileName = md5sum + lib_ext
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   545
            extra_files_log = os.path.join(self.workingdir, "extra_files.txt")
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   546
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   547
            old_PLC_filename = os.path.join(self.workingdir, self.CurrentPLCFilename) \
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   548
                if self.CurrentPLCFilename is not None \
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   549
                else None
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   550
            new_PLC_filename = os.path.join(self.workingdir, NewFileName)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   551
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   552
            # Some platform (i.e. Xenomai) don't like reloading same .so file
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   553
            replace_PLC_shared_object = new_PLC_filename != old_PLC_filename
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   554
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   555
            if replace_PLC_shared_object:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   556
                self.UnLoadPLC()
1045
a220a27defe5 Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents: 1035
diff changeset
   557
1734
750eeb7230a1 clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1732
diff changeset
   558
            self.LogMessage("NewPLC (%s)" % md5sum)
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   559
            self.PLCStatus = "Empty"
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   560
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   561
            try:
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   562
                if replace_PLC_shared_object:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   563
                    os.remove(old_PLC_filename)
364
27ea6a6747fc Bug extra_files deletion in working directory fixed
laurent
parents: 361
diff changeset
   564
                for filename in file(extra_files_log, "r").readlines() + [extra_files_log]:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   565
                    try:
364
27ea6a6747fc Bug extra_files deletion in working directory fixed
laurent
parents: 361
diff changeset
   566
                        os.remove(os.path.join(self.workingdir, filename.strip()))
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   567
                    except Exception:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   568
                        pass
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   569
            except Exception:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   570
                pass
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   571
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   572
            try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   573
                # Create new PLC file
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   574
                if replace_PLC_shared_object:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   575
                    open(new_PLC_filename, 'wb').write(data)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   576
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   577
                # Store new PLC filename based on md5 key
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   578
                open(self._GetMD5FileName(), "w").write(md5sum)
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   579
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   580
                # Then write the files
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   581
                log = file(extra_files_log, "w")
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   582
                for fname, fdata in extrafiles:
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   583
                    fpath = os.path.join(self.workingdir, fname)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   584
                    open(fpath, "wb").write(fdata)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   585
                    log.write(fname+'\n')
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   586
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   587
                # Store new PLC filename
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   588
                self.CurrentPLCFilename = NewFileName
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   589
            except Exception:
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   590
                self.PLCStatus = "Broken"
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   591
                self.StatusChange()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   592
                PLCprint(traceback.format_exc())
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   593
                return False
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   594
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   595
            if not replace_PLC_shared_object:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   596
                self.PLCStatus = "Stopped"
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   597
            elif self.LoadPLC():
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   598
                self.PLCStatus = "Stopped"
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   599
            else:
1035
0f905e027d18 Better mdns resolution failure signaling, added fixed bug whith runtime autostart
Edouard Tisserant
parents: 1027
diff changeset
   600
                self.PLCStatus = "Broken"
906
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   601
            self.StatusChange()
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   602
de452d65865c Python runtime now dlopens shared library immediatly after transfer, and release it only immediately before reloading a new one. This is probably going to reveal lot of dirty cleanups during start/stop cycles.
Edouard Tisserant
parents: 868
diff changeset
   603
            return self.PLCStatus == "Stopped"
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   604
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   605
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   606
    def MatchMD5(self, MD5):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   607
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   608
            last_md5 = open(self._GetMD5FileName(), "r").read()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   609
            return last_md5 == MD5
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   610
        except Exception:
1440
e8daabf2c438 Runtime : Added PLCobject methods registring. IDE : Added WAMP connector. Still need some fixes
Edouard Tisserant
parents: 1438
diff changeset
   611
            pass
e8daabf2c438 Runtime : Added PLCobject methods registring. IDE : Added WAMP connector. Still need some fixes
Edouard Tisserant
parents: 1438
diff changeset
   612
        return False
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   613
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   614
    def SetTraceVariablesList(self, idxs):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   615
        """
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   616
        Call ctype imported function to append
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   617
        these indexes to registred variables in PLC debugger
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   618
        """
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   619
        if idxs:
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   620
            # suspend but dont disable
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   621
            if self._suspendDebug(False) == 0:
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   622
                # keep a copy of requested idx
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   623
                self._ResetDebugVariables()
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   624
                for idx, iectype, force in idxs:
1743
c3c3d1318130 clean-up: fix PEP8 E711 comparison to None should be 'if cond is not None:'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1742
diff changeset
   625
                    if force is not None:
1847
6198190bc121 explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1846
diff changeset
   626
                        c_type, _unpack_func, pack_func = \
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   627
                            TypeTranslator.get(iectype,
1767
c74815729afd clean-up: fix PEP8 E127 continuation line over-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1760
diff changeset
   628
                                               (None, None, None))
1740
b789b695b5c6 clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1739
diff changeset
   629
                        force = ctypes.byref(pack_func(c_type, force))
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   630
                    self._RegisterDebugVariable(idx, force)
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   631
                self._TracesSwap()
614
eed1dcf311a1 added return type to suspendDebug
Edouard Tisserant
parents: 593
diff changeset
   632
                self._resumeDebug()
462
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   633
        else:
274e83a5534e Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 461
diff changeset
   634
            self._suspendDebug(True)
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   635
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   636
    def _TracesSwap(self):
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   637
        self.LastSwapTrace = time()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   638
        if self.TraceThread is None and self.PLCStatus == "Started":
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   639
            self.TraceThread = Thread(target=self.TraceThreadProc)
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   640
            self.TraceThread.start()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   641
        self.TraceLock.acquire()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   642
        Traces = self.Traces
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   643
        self.Traces = []
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   644
        self.TraceLock.release()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   645
        return Traces
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   646
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   647
    @RunInMain
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   648
    def GetTraceVariables(self):
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   649
        return self.PLCStatus, self._TracesSwap()
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   650
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   651
    def TraceThreadProc(self):
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   652
        """
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   653
        Return a list of traces, corresponding to the list of required idx
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   654
        """
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   655
        self._resumeDebug()  # Re-enable debugger
1739
ec153828ded2 clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1737
diff changeset
   656
        while self.PLCStatus == "Started":
450
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   657
            tick = ctypes.c_uint32()
18583d13f0fa Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents: 446
diff changeset
   658
            size = ctypes.c_uint32()
1075
8078c01ae464 Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents: 1074
diff changeset
   659
            buff = ctypes.c_void_p()
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   660
            TraceBuffer = None
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   661
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   662
            self.PLClibraryLock.acquire()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   663
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   664
            res = self._GetDebugData(ctypes.byref(tick),
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   665
                                     ctypes.byref(size),
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   666
                                     ctypes.byref(buff))
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   667
            if res == 0:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   668
                if size.value:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   669
                    TraceBuffer = ctypes.string_at(buff.value, size.value)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   670
                self._FreeDebugData()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   671
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   672
            self.PLClibraryLock.release()
1997
d9e8fb47340f PEP-8 and PyLint
Edouard Tisserant
parents: 1994
diff changeset
   673
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   674
            # leave thread if GetDebugData isn't happy.
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   675
            if res != 0:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   676
                break
1990
2e0fbdd152de Fixed Xenomai 3 PLC stop freeze. Now use explicit finish command with pipes. Closing both ends of pipes doesn't abort blocking read anymore.
Edouard Tisserant
parents: 1988
diff changeset
   677
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   678
            if TraceBuffer is not None:
1994
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   679
                self.TraceLock.acquire()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   680
                lT = len(self.Traces)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   681
                if lT != 0 and lT * len(self.Traces[0]) > 1024 * 1024:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   682
                    self.Traces.pop(0)
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   683
                self.Traces.append((tick.value, TraceBuffer))
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   684
                self.TraceLock.release()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   685
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   686
            # TraceProc stops here if Traces not polled for 3 seconds
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   687
            traces_age = time() - self.LastSwapTrace
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   688
            if traces_age > 3:
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   689
                self.TraceLock.acquire()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   690
                self.Traces = []
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   691
                self.TraceLock.release()
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   692
                self._suspendDebug(True)  # Disable debugger
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   693
                break
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   694
1fdc32be71b8 Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents: 1993
diff changeset
   695
        self.TraceThread = None
1434
6e0cd0ceabb7 Added runtime side trace buffer, handled in a separate thread, limited to 1MB, and dropped after 3 seconds if not used by IDE. GetTraceVariables is not anymore blocking on next PLC cycle
Edouard Tisserant
parents: 1433
diff changeset
   696
1440
e8daabf2c438 Runtime : Added PLCobject methods registring. IDE : Added WAMP connector. Still need some fixes
Edouard Tisserant
parents: 1438
diff changeset
   697
    def RemoteExec(self, script, *kwargs):
699
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   698
        try:
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   699
            exec script in kwargs
1780
c52d1460cea8 clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1768
diff changeset
   700
        except Exception:
1847
6198190bc121 explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1846
diff changeset
   701
            _e_type, e_value, e_traceback = sys.exc_info()
699
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   702
            line_no = traceback.tb_lineno(get_last_traceback(e_traceback))
1433
4a45f6642523 Moved trace buffer unpacking in the IDE. Latest traced variable samples are now passed as a single string
Edouard Tisserant
parents: 1288
diff changeset
   703
            return (-1, "RemoteExec script failed!\n\nLine %d: %s\n\t%s" %
1878
fb73a6b6622d fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1868
diff changeset
   704
                    (line_no, e_value, script.splitlines()[line_no - 1]))
699
6ff64cadb1ff Adding support for executing python scripts on remote runtime
laurent
parents: 690
diff changeset
   705
        return (0, kwargs.get("returnVal", None))