author | Edouard Tisserant |
Wed, 21 Sep 2022 11:51:05 +0200 | |
changeset 3623 | 0237c28cd172 |
parent 3578 | d74eb1be6abe |
child 3642 | cd3d15e8ef42 |
child 3861 | 7e17f7e02a2b |
permissions | -rw-r--r-- |
229 | 1 |
#!/usr/bin/env python |
2 |
# -*- coding: utf-8 -*- |
|
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 | 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 | 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 | 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 | 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 |
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
26 |
from threading import Thread, Lock, Event, Condition |
1732
94ffe74e6895
clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
27 |
import ctypes |
94ffe74e6895
clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
28 |
import os |
94ffe74e6895
clean-up: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
29 |
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
|
30 |
import traceback |
2537
eb4a4cc41914
Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2492
diff
changeset
|
31 |
import shutil |
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 |
2540
fca79ca84272
Replace md5 module with hashlib
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2537
diff
changeset
|
33 |
import hashlib |
2537
eb4a4cc41914
Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2492
diff
changeset
|
34 |
from tempfile import mkstemp |
eb4a4cc41914
Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2492
diff
changeset
|
35 |
from functools import wraps, partial |
2492
7dd551ac2fa0
check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2487
diff
changeset
|
36 |
from six.moves import xrange |
2443
75a274023970
python3 support: pylint, W1606 # (execfile-builtin) execfile built-in referenced
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2442
diff
changeset
|
37 |
from past.builtins import execfile |
2537
eb4a4cc41914
Fix various pylint and pep8 errors
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2492
diff
changeset
|
38 |
import _ctypes |
1832
0f1081928d65
fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1831
diff
changeset
|
39 |
|
1902
2b7e2db31d81
Clarify licensing, and packaging of runtime only files :
Edouard Tisserant
parents:
1881
diff
changeset
|
40 |
from runtime.typemapping import TypeTranslator |
2b7e2db31d81
Clarify licensing, and packaging of runtime only files :
Edouard Tisserant
parents:
1881
diff
changeset
|
41 |
from runtime.loglevels import LogLevelsDefault, LogLevelsCount |
2324
1cf3768ebf85
Automatically get PSK and ID when connecting to PYRO[S], so that future connection through PYROS can use that same key. Also fixed case to UPPER for *PSK.
Edouard Tisserant
parents:
2309
diff
changeset
|
42 |
from runtime.Stunnel import getPSKID |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
43 |
from runtime import PlcStatus |
2270
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
44 |
from runtime import MainWorker |
2583
e172ab28d04e
Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents:
2582
diff
changeset
|
45 |
from runtime import default_evaluator |
917 | 46 |
|
229 | 47 |
if os.name in ("nt", "ce"): |
1919
ccea0fa6ea91
Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents:
1906
diff
changeset
|
48 |
dlopen = _ctypes.LoadLibrary |
ccea0fa6ea91
Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents:
1906
diff
changeset
|
49 |
dlclose = _ctypes.FreeLibrary |
229 | 50 |
elif os.name == "posix": |
1919
ccea0fa6ea91
Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents:
1906
diff
changeset
|
51 |
dlopen = _ctypes.dlopen |
ccea0fa6ea91
Another set of meaningless changes to satisfy PEP8 and PyLint.
Edouard Tisserant
parents:
1906
diff
changeset
|
52 |
dlclose = _ctypes.dlclose |
229 | 53 |
|
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
54 |
|
699
6ff64cadb1ff
Adding support for executing python scripts on remote runtime
laurent
parents:
690
diff
changeset
|
55 |
def get_last_traceback(tb): |
6ff64cadb1ff
Adding support for executing python scripts on remote runtime
laurent
parents:
690
diff
changeset
|
56 |
while tb.tb_next: |
6ff64cadb1ff
Adding support for executing python scripts on remote runtime
laurent
parents:
690
diff
changeset
|
57 |
tb = tb.tb_next |
6ff64cadb1ff
Adding support for executing python scripts on remote runtime
laurent
parents:
690
diff
changeset
|
58 |
return tb |
229 | 59 |
|
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
|
60 |
|
1742
92932cd370a4
clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1741
diff
changeset
|
61 |
lib_ext = { |
1878
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1868
diff
changeset
|
62 |
"linux2": ".so", |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1868
diff
changeset
|
63 |
"win32": ".dll", |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1868
diff
changeset
|
64 |
}.get(sys.platform, "") |
229 | 65 |
|
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
66 |
|
291
701c0601db02
Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents:
290
diff
changeset
|
67 |
def PLCprint(message): |
701c0601db02
Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents:
290
diff
changeset
|
68 |
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
|
69 |
sys.stdout.flush() |
701c0601db02
Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents:
290
diff
changeset
|
70 |
|
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
71 |
|
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
|
72 |
def RunInMain(func): |
2486
44c2a4e2b84d
Fixed deadlock in runtime's Worker. Was discovered while using WAMP and PYRO simultaneously.
Edouard Tisserant
parents:
2485
diff
changeset
|
73 |
@wraps(func) |
1997 | 74 |
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
|
75 |
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
|
76 |
return func_wrapper |
1997 | 77 |
|
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
|
78 |
|
2270
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
79 |
class PLCObject(object): |
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
80 |
def __init__(self, WorkingDir, argv, statuschange, evaluator, pyruntimevars): |
2492
7dd551ac2fa0
check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2487
diff
changeset
|
81 |
self.workingdir = WorkingDir # must exits already |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
82 |
self.tmpdir = os.path.join(WorkingDir, 'tmp') |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
83 |
if os.path.exists(self.tmpdir): |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
84 |
shutil.rmtree(self.tmpdir) |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
85 |
os.mkdir(self.tmpdir) |
2270
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
86 |
# FIXME : is argv of any use nowadays ? |
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
87 |
self.argv = [WorkingDir] + argv # force argv[0] to be "path" to exec... |
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
88 |
self.statuschange = statuschange |
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
89 |
self.evaluator = evaluator |
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
90 |
self.pyruntimevars = pyruntimevars |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
91 |
self.PLCStatus = PlcStatus.Empty |
229 | 92 |
self.PLClibraryHandle = None |
352 | 93 |
self.PLClibraryLock = Lock() |
229 | 94 |
# 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
|
95 |
self._InitPLCStubCalls() |
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
|
96 |
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
|
97 |
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
|
98 |
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
|
99 |
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
|
100 |
self.Traces = [] |
2485
ef327451d067
Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents:
2463
diff
changeset
|
101 |
self.DebugToken = 0 |
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
|
102 |
|
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
103 |
self._init_blobs() |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
104 |
|
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
105 |
# First task of worker -> no @RunInMain |
2270
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
106 |
def AutoLoad(self, autostart): |
1997 | 107 |
# Get the last transfered PLC |
229 | 108 |
try: |
1742
92932cd370a4
clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1741
diff
changeset
|
109 |
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
|
110 |
self._GetMD5FileName(), |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1868
diff
changeset
|
111 |
"r").read().strip() + lib_ext |
2608
a332f989f0b8
Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents:
2602
diff
changeset
|
112 |
self.PLCStatus = PlcStatus.Stopped |
a332f989f0b8
Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents:
2602
diff
changeset
|
113 |
if autostart: |
a332f989f0b8
Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents:
2602
diff
changeset
|
114 |
if self.LoadPLC(): |
2270
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
115 |
self.StartPLC() |
3282
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
116 |
else: |
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
117 |
self._fail(_("Problem autostarting PLC : can't load PLC")) |
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
118 |
return |
1846
14b40afccd69
remove unused variables found by pylint
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1832
diff
changeset
|
119 |
except Exception: |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
120 |
self.PLCStatus = PlcStatus.Empty |
1742
92932cd370a4
clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1741
diff
changeset
|
121 |
self.CurrentPLCFilename = None |
229 | 122 |
|
2270
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
123 |
self.StatusChange() |
d9175daf6522
Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
1997
diff
changeset
|
124 |
|
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
|
125 |
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
|
126 |
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
|
127 |
for callee in self.statuschange: |
19ebe96b41c0
Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents:
1435
diff
changeset
|
128 |
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
|
129 |
|
917 | 130 |
def LogMessage(self, *args): |
131 |
if len(args) == 2: |
|
132 |
level, msg = args |
|
133 |
else: |
|
134 |
level = LogLevelsDefault |
|
135 |
msg, = args |
|
1906
60edd0c901f1
Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents:
1902
diff
changeset
|
136 |
PLCprint(msg) |
60edd0c901f1
Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents:
1902
diff
changeset
|
137 |
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
|
138 |
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
|
139 |
return None |
917 | 140 |
|
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
141 |
@RunInMain |
1093 | 142 |
def ResetLogCount(self): |
143 |
if self._ResetLogCount is not None: |
|
144 |
self._ResetLogCount() |
|
917 | 145 |
|
1997 | 146 |
# used internaly |
917 | 147 |
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
|
148 |
if self._GetLogCount is not None: |
917 | 149 |
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
|
150 |
elif self._loading_error is not None and level == 0: |
1093 | 151 |
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
|
152 |
|
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
153 |
@RunInMain |
917 | 154 |
def GetLogMessage(self, level, msgid): |
921 | 155 |
tick = ctypes.c_uint32() |
156 |
tv_sec = ctypes.c_uint32() |
|
157 |
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
|
158 |
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
|
159 |
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
|
160 |
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
|
161 |
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
|
162 |
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
|
163 |
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
|
164 |
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
|
165 |
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
|
166 |
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
|
167 |
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
|
168 |
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
|
169 |
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
|
170 |
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
|
171 |
|
229 | 172 |
def _GetMD5FileName(self): |
173 |
return os.path.join(self.workingdir, "lasttransferedPLC.md5") |
|
174 |
||
175 |
def _GetLibFileName(self): |
|
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
176 |
return os.path.join(self.workingdir, self.CurrentPLCFilename) |
229 | 177 |
|
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
178 |
def _LoadPLC(self): |
229 | 179 |
""" |
180 |
Load PLC library |
|
181 |
Declare all functions, arguments and return values |
|
182 |
""" |
|
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
|
183 |
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
|
184 |
self.PLClibraryLock.acquire() |
229 | 185 |
try: |
186 |
self._PLClibraryHandle = dlopen(self._GetLibFileName()) |
|
187 |
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
|
188 |
|
1463
de311ffe3961
Changed runtime's global PLCID to PLC_ID, working around redefinition in windoze' headers.
Edouard Tisserant
parents:
1457
diff
changeset
|
189 |
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
|
190 |
if len(md5) == 32: |
1730
64d8f52bc8c8
clean-up for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1667
diff
changeset
|
191 |
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
|
192 |
|
229 | 193 |
self._startPLC = self.PLClibraryHandle.startPLC |
194 |
self._startPLC.restype = ctypes.c_int |
|
195 |
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
|
196 |
|
455
e050ef5bd285
Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents:
450
diff
changeset
|
197 |
self._stopPLC_real = self.PLClibraryHandle.stopPLC |
e050ef5bd285
Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents:
450
diff
changeset
|
198 |
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
|
199 |
|
366
cd90e4c10261
Move python evaluator to create a python plugin containing any related python module
laurent
parents:
365
diff
changeset
|
200 |
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
|
201 |
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
|
202 |
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
|
203 |
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
|
204 |
|
483
bc26c42d2eec
fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents:
479
diff
changeset
|
205 |
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
|
206 |
else: |
717 | 207 |
# 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
|
208 |
# 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
|
209 |
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
|
210 |
|
868
7e5da4962bea
Fix bug of PythonIterator signature in PLCObject when not using PythonLibrary
Edouard Tisserant
parents:
867
diff
changeset
|
211 |
def PythonIterator(res, blkid): |
1442
ad9a7853dea2
Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents:
1440
diff
changeset
|
212 |
self.PlcStopping.clear() |
ad9a7853dea2
Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents:
1440
diff
changeset
|
213 |
self.PlcStopping.wait() |
366
cd90e4c10261
Move python evaluator to create a python plugin containing any related python module
laurent
parents:
365
diff
changeset
|
214 |
return None |
455
e050ef5bd285
Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents:
450
diff
changeset
|
215 |
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
|
216 |
|
483
bc26c42d2eec
fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents:
479
diff
changeset
|
217 |
def __StopPLC(): |
455
e050ef5bd285
Refactoring in PLCobject, for PLC that do not use python plugin
ed
parents:
450
diff
changeset
|
218 |
self._stopPLC_real() |
1442
ad9a7853dea2
Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents:
1440
diff
changeset
|
219 |
self.PlcStopping.set() |
483
bc26c42d2eec
fixed greg's crap in win32, enhanced debug stability, implemented preliminary retain
edouard
parents:
479
diff
changeset
|
220 |
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
|
221 |
|
229 | 222 |
self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables |
223 |
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
|
224 |
|
235 | 225 |
self._RegisterDebugVariable = self.PLClibraryHandle.RegisterDebugVariable |
3395
93ad018fb602
RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents:
3282
diff
changeset
|
226 |
self._RegisterDebugVariable.restype = ctypes.c_int |
477
f66a092b6e74
Arbitrary variable forcing
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
467
diff
changeset
|
227 |
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
|
228 |
|
229 | 229 |
self._FreeDebugData = self.PLClibraryHandle.FreeDebugData |
230 |
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
|
231 |
|
450
18583d13f0fa
Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
446
diff
changeset
|
232 |
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
|
233 |
self._GetDebugData.restype = ctypes.c_int |
450
18583d13f0fa
Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
446
diff
changeset
|
234 |
self._GetDebugData.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_void_p)] |
235 | 235 |
|
236 |
self._suspendDebug = self.PLClibraryHandle.suspendDebug |
|
614 | 237 |
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
|
238 |
self._suspendDebug.argtypes = [ctypes.c_int] |
235 | 239 |
|
240 |
self._resumeDebug = self.PLClibraryHandle.resumeDebug |
|
241 |
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
|
242 |
|
1093 | 243 |
self._ResetLogCount = self.PLClibraryHandle.ResetLogCount |
244 |
self._ResetLogCount.restype = None |
|
245 |
||
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
|
246 |
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
|
247 |
self._GetLogCount.restype = ctypes.c_uint32 |
917 | 248 |
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
|
249 |
|
911
ffa24427396a
Log redirected to console, dump of all available log to console when connecting to PLC
Edouard Tisserant
parents:
906
diff
changeset
|
250 |
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
|
251 |
self._LogMessage.restype = ctypes.c_int |
971
c4550f76ae05
reverted PLCObject.py. ctypes.POINTER(ctypes.c_uint8) != string
Edouard Tisserant
parents:
969
diff
changeset
|
252 |
self._LogMessage.argtypes = [ctypes.c_uint8, ctypes.c_char_p, ctypes.c_uint32] |
1093 | 253 |
|
1760
ed2e2afb9573
clean-up: fix PEP8 E262 inline comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1750
diff
changeset
|
254 |
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
|
255 |
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
|
256 |
self._GetLogMessage.restype = ctypes.c_uint32 |
921 | 257 |
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
|
258 |
|
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
|
259 |
self._loading_error = None |
1035
0f905e027d18
Better mdns resolution failure signaling, added fixed bug whith runtime autostart
Edouard Tisserant
parents:
1027
diff
changeset
|
260 |
|
1780
c52d1460cea8
clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1768
diff
changeset
|
261 |
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
|
262 |
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
|
263 |
PLCprint(self._loading_error) |
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
264 |
return False |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
265 |
finally: |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
266 |
self.PLClibraryLock.release() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
267 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
268 |
return True |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
269 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
270 |
@RunInMain |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
271 |
def LoadPLC(self): |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
272 |
res = self._LoadPLC() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
273 |
if res: |
3282
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
274 |
try: |
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
275 |
self.PythonRuntimeInit() |
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
276 |
except Exception: |
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
277 |
self._loading_error = traceback.format_exc() |
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
278 |
PLCprint(self._loading_error) |
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
279 |
return False |
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
280 |
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
|
281 |
self._FreePLC() |
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
282 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
283 |
return res |
229 | 284 |
|
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
|
285 |
@RunInMain |
1045
a220a27defe5
Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents:
1035
diff
changeset
|
286 |
def UnLoadPLC(self): |
a220a27defe5
Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents:
1035
diff
changeset
|
287 |
self.PythonRuntimeCleanup() |
a220a27defe5
Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents:
1035
diff
changeset
|
288 |
self._FreePLC() |
a220a27defe5
Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents:
1035
diff
changeset
|
289 |
|
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
|
290 |
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
|
291 |
""" |
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
|
292 |
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
|
293 |
""" |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
294 |
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
|
295 |
self._stopPLC = lambda: None |
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
296 |
self._ResetDebugVariables = lambda: None |
3395
93ad018fb602
RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents:
3282
diff
changeset
|
297 |
self._RegisterDebugVariable = lambda x, y: 0 |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
298 |
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
|
299 |
self._FreeDebugData = lambda: None |
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
300 |
self._GetDebugData = lambda: -1 |
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
301 |
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
|
302 |
self._resumeDebug = lambda: None |
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
303 |
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
|
304 |
self._GetLogCount = None |
1906
60edd0c901f1
Trying to get better logging/display of exceptions at runtime's startup
Edouard Tisserant
parents:
1902
diff
changeset
|
305 |
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
|
306 |
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
|
307 |
self._PLClibraryHandle = None |
229 | 308 |
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
|
309 |
|
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
|
310 |
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
|
311 |
""" |
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
|
312 |
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
|
313 |
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
|
314 |
""" |
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
|
315 |
self.PLClibraryLock.acquire() |
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
316 |
try: |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
317 |
# Unload library explicitely |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
318 |
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
|
319 |
dlclose(self._PLClibraryHandle) |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
320 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
321 |
# Forget all refs to library |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
322 |
self._InitPLCStubCalls() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
323 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
324 |
finally: |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
325 |
self.PLClibraryLock.release() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
326 |
|
229 | 327 |
return False |
328 |
||
2635
ae099881d800
PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents:
2625
diff
changeset
|
329 |
def PythonRuntimeCall(self, methodname, use_evaluator=True, reverse_order=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
|
330 |
""" |
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
|
331 |
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
|
332 |
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
|
333 |
""" |
2635
ae099881d800
PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents:
2625
diff
changeset
|
334 |
methods = self.python_runtime_vars.get("_runtime_%s" % methodname, []) |
ae099881d800
PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents:
2625
diff
changeset
|
335 |
if reverse_order: |
ae099881d800
PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents:
2625
diff
changeset
|
336 |
methods = reversed(methods) |
ae099881d800
PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents:
2625
diff
changeset
|
337 |
for method in methods: |
2583
e172ab28d04e
Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents:
2582
diff
changeset
|
338 |
if use_evaluator: |
e172ab28d04e
Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents:
2582
diff
changeset
|
339 |
_res, exp = self.evaluator(method) |
e172ab28d04e
Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents:
2582
diff
changeset
|
340 |
else: |
e172ab28d04e
Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents:
2582
diff
changeset
|
341 |
_res, exp = default_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
|
342 |
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
|
343 |
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
|
344 |
|
1997 | 345 |
# used internaly |
1014
e2f7d6c95db0
Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents:
1011
diff
changeset
|
346 |
def PythonRuntimeInit(self): |
e2f7d6c95db0
Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents:
1011
diff
changeset
|
347 |
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
|
348 |
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
|
349 |
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
|
350 |
parent = self |
1438
19ebe96b41c0
Moved twisted/nevow/athena away from Berermiz_service.py + some minor cleanup
Edouard Tisserant
parents:
1435
diff
changeset
|
351 |
|
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
|
352 |
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
|
353 |
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
|
354 |
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
|
355 |
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
|
356 |
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
|
357 |
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
|
358 |
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
|
359 |
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
|
360 |
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
|
361 |
|
616c3f4bcbcb
fix pylint error '(no-self-argument) Method should have "self" as first argument'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1850
diff
changeset
|
362 |
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
|
363 |
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
|
364 |
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
|
365 |
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
|
366 |
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
|
367 |
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
|
368 |
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
|
369 |
|
2697
93333d206198
Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2689
diff
changeset
|
370 |
class OnChangeStateClass(object): |
93333d206198
Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2689
diff
changeset
|
371 |
def __getattr__(self, name): |
93333d206198
Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2689
diff
changeset
|
372 |
u = parent.python_runtime_vars["_"+name+"_unpack"] |
2698
e50d32c747b3
Fixed "Onchange" object added in previous commit
Edouard Tisserant
parents:
2697
diff
changeset
|
373 |
return type("changedesc",(),dict( |
e50d32c747b3
Fixed "Onchange" object added in previous commit
Edouard Tisserant
parents:
2697
diff
changeset
|
374 |
count = parent.python_runtime_vars["_PyOnChangeCount_"+name].value, |
e50d32c747b3
Fixed "Onchange" object added in previous commit
Edouard Tisserant
parents:
2697
diff
changeset
|
375 |
first = u(parent.python_runtime_vars["_PyOnChangeFirst_"+name]), |
e50d32c747b3
Fixed "Onchange" object added in previous commit
Edouard Tisserant
parents:
2697
diff
changeset
|
376 |
last = u(parent.python_runtime_vars["_PyOnChangeLast_"+name]))) |
2697
93333d206198
Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2689
diff
changeset
|
377 |
|
93333d206198
Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2689
diff
changeset
|
378 |
|
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
|
379 |
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
|
380 |
"PLCGlobals": PLCSafeGlobals(), |
2697
93333d206198
Python Safe Globals now have more reliable triggering of OnChange call. Added "Onchange" object to accessible runtime variables that let user python code see count of changes and first and last values.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2689
diff
changeset
|
381 |
"OnChange": OnChangeStateClass(), |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1737
diff
changeset
|
382 |
"WorkingDir": self.workingdir, |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1737
diff
changeset
|
383 |
"PLCObject": self, |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1737
diff
changeset
|
384 |
"PLCBinary": self.PLClibraryHandle, |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1737
diff
changeset
|
385 |
"PLCGlobalsDesc": []}) |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1737
diff
changeset
|
386 |
|
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1737
diff
changeset
|
387 |
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
|
388 |
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
|
389 |
|
972 | 390 |
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
|
391 |
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
|
392 |
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
|
393 |
for filename in filenames: |
972 | 394 |
name, ext = os.path.splitext(filename) |
395 |
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
|
396 |
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
|
397 |
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
|
398 |
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
|
399 |
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
|
400 |
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
|
401 |
except Exception: |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
402 |
self.LogMessage(0, traceback.format_exc()) |
972 | 403 |
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
|
404 |
|
2583
e172ab28d04e
Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents:
2582
diff
changeset
|
405 |
self.PythonRuntimeCall("init", use_evaluator=False) |
e172ab28d04e
Continue fixing deadlock of previous commit, this time occuring when waiting for 'cleanup' python runtime call to finish. Now 'init' and 'cleanup' python runtime calls are called directly from main thread, and aren't anymore invoked in the context of wxMainloop and/or twisted reactor.
Edouard Tisserant
parents:
2582
diff
changeset
|
406 |
|
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
407 |
self.PythonThreadCondLock = Lock() |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
408 |
self.PythonThreadCmdCond = Condition(self.PythonThreadCondLock) |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
409 |
self.PythonThreadAckCond = Condition(self.PythonThreadCondLock) |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
410 |
self.PythonThreadCmd = None |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
411 |
self.PythonThreadAck = None |
2600
0e20a0d48fae
Named runtime's threads to ease debugging
Edouard Tisserant
parents:
2596
diff
changeset
|
412 |
self.PythonThread = Thread(target=self.PythonThreadProc, name="PLCPythonThread") |
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
413 |
self.PythonThread.start() |
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
414 |
|
1997 | 415 |
# used internaly |
1014
e2f7d6c95db0
Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents:
1011
diff
changeset
|
416 |
def PythonRuntimeCleanup(self): |
e2f7d6c95db0
Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents:
1011
diff
changeset
|
417 |
if self.python_runtime_vars is not None: |
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
418 |
self.PythonThreadCommand("Finish") |
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
419 |
self.PythonThread.join() |
2635
ae099881d800
PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents:
2625
diff
changeset
|
420 |
self.PythonRuntimeCall("cleanup", use_evaluator=False, reverse_order=True) |
1014
e2f7d6c95db0
Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents:
1011
diff
changeset
|
421 |
|
e2f7d6c95db0
Now python files provided by extentions have init, start, stop and cleanup hooks
Edouard Tisserant
parents:
1011
diff
changeset
|
422 |
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
|
423 |
|
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
424 |
def PythonThreadLoop(self): |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
425 |
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
|
426 |
compile_cache = {} |
798
0d2423f283a6
Fix bug segmentation fault while cleanup extensions
laurent
parents:
795
diff
changeset
|
427 |
while True: |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
428 |
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
|
429 |
FBID = blkid.value |
798
0d2423f283a6
Fix bug segmentation fault while cleanup extensions
laurent
parents:
795
diff
changeset
|
430 |
if cmd is None: |
0d2423f283a6
Fix bug segmentation fault while cleanup extensions
laurent
parents:
795
diff
changeset
|
431 |
break |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1737
diff
changeset
|
432 |
try: |
1742
92932cd370a4
clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1741
diff
changeset
|
433 |
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
|
434 |
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
|
435 |
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
|
436 |
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
|
437 |
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
|
438 |
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
|
439 |
if exp is not None: |
1052
fa7c5034c1d2
Better display of Python exceptions from Py_Eval
Edouard Tisserant
parents:
1051
diff
changeset
|
440 |
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
|
441 |
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
|
442 |
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
|
443 |
else: |
1742
92932cd370a4
clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1741
diff
changeset
|
444 |
res = str(result) |
92932cd370a4
clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1741
diff
changeset
|
445 |
self.python_runtime_vars["FBID"] = None |
2418
5587c490a070
Use python 3 compatible exception syntax everywhere
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2416
diff
changeset
|
446 |
except Exception as e: |
798
0d2423f283a6
Fix bug segmentation fault while cleanup extensions
laurent
parents:
795
diff
changeset
|
447 |
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
|
448 |
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
|
449 |
|
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
450 |
def PythonThreadProc(self): |
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
451 |
while True: |
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
452 |
self.PythonThreadCondLock.acquire() |
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
453 |
cmd = self.PythonThreadCmd |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
454 |
while cmd is None: |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
455 |
self.PythonThreadCmdCond.wait() |
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
456 |
cmd = self.PythonThreadCmd |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
457 |
self.PythonThreadCmd = None |
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
458 |
self.PythonThreadCondLock.release() |
2586 | 459 |
|
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
460 |
if cmd == "PreStart": |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
461 |
self.PreStartPLC() |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
462 |
# Ack once PreStart done, must be finished before StartPLC |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
463 |
self.PythonThreadAcknowledge(cmd) |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
464 |
elif cmd == "Start": |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
465 |
# Ack Immediately, for responsiveness |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
466 |
self.PythonThreadAcknowledge(cmd) |
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
467 |
self.PythonRuntimeCall("start") |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
468 |
self.LogMessage("Python extensions started") |
3578
d74eb1be6abe
Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents:
3577
diff
changeset
|
469 |
self._PostStartPLC() |
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
470 |
self.PythonThreadLoop() |
2635
ae099881d800
PLCobject: Call "stop" and "cleanup" methods from python runtime files in reverse order compared to "init" and "start".
Edouard Tisserant
parents:
2625
diff
changeset
|
471 |
self.PythonRuntimeCall("stop", reverse_order=True) |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
472 |
elif cmd == "Finish": |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
473 |
self.PythonThreadAcknowledge(cmd) |
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
474 |
break |
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
475 |
|
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
476 |
def PythonThreadAcknowledge(self, ack): |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
477 |
self.PythonThreadCondLock.acquire() |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
478 |
self.PythonThreadAck = ack |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
479 |
self.PythonThreadAckCond.notify() |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
480 |
self.PythonThreadCondLock.release() |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
481 |
|
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
482 |
def PythonThreadCommand(self, cmd): |
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
483 |
self.PythonThreadCondLock.acquire() |
2586 | 484 |
self.PythonThreadCmd = cmd |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
485 |
self.PythonThreadCmdCond.notify() |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
486 |
ack = None |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
487 |
while ack != cmd: |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
488 |
self.PythonThreadAckCond.wait() |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
489 |
ack = self.PythonThreadAck |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
490 |
self.PythonThreadAck = None |
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
491 |
|
2582
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
492 |
self.PythonThreadCondLock.release() |
8f0d6c5fd55f
Fix deadlock when indirectly calling PLCObject's evaluator() from twisted of wx event loops. Was freezing while transfer/start/stop through Wamp. Serialize all PLCObject's call to self.PythonRuntimeCall into the same PythonThread thread.
Edouard Tisserant
parents:
2546
diff
changeset
|
493 |
|
2682
4d3320fdab19
Runtime: Fix typo in PLCObject leading to exception when reporting failure.
Edouard Tisserant
parents:
2678
diff
changeset
|
494 |
def _fail(self, msg): |
2646
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
495 |
self.LogMessage(0, msg) |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
496 |
self.PLCStatus = PlcStatus.Broken |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
497 |
self.StatusChange() |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
498 |
|
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
499 |
def PreStartPLC(self): |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
500 |
""" |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
501 |
Here goes actions to be taken just before PLC starts, |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
502 |
with all libraries and python object already created. |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
503 |
For example : restore saved proprietary parameters |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
504 |
""" |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
505 |
pass |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
506 |
|
3578
d74eb1be6abe
Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents:
3577
diff
changeset
|
507 |
def _PostStartPLC(self): |
d74eb1be6abe
Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents:
3577
diff
changeset
|
508 |
try: |
d74eb1be6abe
Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents:
3577
diff
changeset
|
509 |
self.PostStartPLC() |
d74eb1be6abe
Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents:
3577
diff
changeset
|
510 |
except Exception: |
d74eb1be6abe
Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents:
3577
diff
changeset
|
511 |
self.LogMessage(0, 'Post Start Exception'+'\n'.join( |
d74eb1be6abe
Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents:
3577
diff
changeset
|
512 |
traceback.format_exception(*sys.exc_info()))) |
d74eb1be6abe
Runtime: Fix PLC python thread crash in case of exception in PostStart customization hook.
Edouard Tisserant
parents:
3577
diff
changeset
|
513 |
|
2732
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
514 |
def PostStartPLC(self): |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
515 |
""" |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
516 |
Here goes actions to be taken after PLC is started, |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
517 |
with all libraries and python object already created, |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
518 |
and python extensions "Start" methods being called. |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
519 |
This is called before python thread processing py_eval blocks starts. |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
520 |
For example : attach additional ressource to web services |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
521 |
""" |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
522 |
pass |
a3f0e4148714
Runtime: Added PostStart methot to PLCObject, called after PLC is started, with all libraries and python object already created, and python extensions "Start" methods being called.
Edouard Tisserant
parents:
2720
diff
changeset
|
523 |
|
1988
19ca02e8074f
PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents:
1987
diff
changeset
|
524 |
@RunInMain |
462
274e83a5534e
Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
461
diff
changeset
|
525 |
def StartPLC(self): |
2608
a332f989f0b8
Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents:
2602
diff
changeset
|
526 |
|
a332f989f0b8
Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents:
2602
diff
changeset
|
527 |
if self.PLClibraryHandle is None: |
a332f989f0b8
Avoid loading PLC at startup when autostart is not set in command line. As a side effect PLC status is artificially set to Stopped, and StartPLC eventually loads PLC if it is not already loaded.
Edouard Tisserant
parents:
2602
diff
changeset
|
528 |
if not self.LoadPLC(): |
2646
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
529 |
self._fail(_("Problem starting PLC : can't load PLC")) |
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
530 |
|
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
531 |
if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped: |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
532 |
self.PythonThreadCommand("PreStart") |
798
0d2423f283a6
Fix bug segmentation fault while cleanup extensions
laurent
parents:
795
diff
changeset
|
533 |
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
|
534 |
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
|
535 |
if res == 0: |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
536 |
self.LogMessage("PLC started") |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
537 |
self.PLCStatus = PlcStatus.Started |
1442
ad9a7853dea2
Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents:
1440
diff
changeset
|
538 |
self.StatusChange() |
2720
971bb3503957
PLCObject : Ensure that PreStart is executed before starting PLC. Also, make sure that python thread doesn't enter in a start/stop loop when ordered to stop.
Edouard Tisserant
parents:
2702
diff
changeset
|
539 |
self.PythonThreadCommand("Start") |
798
0d2423f283a6
Fix bug segmentation fault while cleanup extensions
laurent
parents:
795
diff
changeset
|
540 |
else: |
2646
d692e01d94f4
PLCObject : reorganize code in StartPLC(), add a PreStartPLC() empty method, to be overloaded by runtime extensions.
Edouard Tisserant
parents:
2635
diff
changeset
|
541 |
self._fail(_("Problem starting PLC : error %d" % res)) |
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
|
542 |
|
1988
19ca02e8074f
PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents:
1987
diff
changeset
|
543 |
@RunInMain |
229 | 544 |
def StopPLC(self): |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
545 |
if self.PLCStatus == PlcStatus.Started: |
917 | 546 |
self.LogMessage("PLC stopped") |
352 | 547 |
self._stopPLC() |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
548 |
self.PLCStatus = PlcStatus.Stopped |
1442
ad9a7853dea2
Fixed race condition preventing to stop PLC through WAMP
Edouard Tisserant
parents:
1440
diff
changeset
|
549 |
self.StatusChange() |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1737
diff
changeset
|
550 |
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
|
551 |
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
|
552 |
self.TraceThread = None |
229 | 553 |
return True |
554 |
return False |
|
555 |
||
556 |
def GetPLCstatus(self): |
|
2602
19dc6b830e7d
If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents:
2600
diff
changeset
|
557 |
try: |
19dc6b830e7d
If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents:
2600
diff
changeset
|
558 |
return self._GetPLCstatus() |
19dc6b830e7d
If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents:
2600
diff
changeset
|
559 |
except EOFError: |
19dc6b830e7d
If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents:
2600
diff
changeset
|
560 |
return (PlcStatus.Disconnected, None) |
19dc6b830e7d
If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents:
2600
diff
changeset
|
561 |
|
19dc6b830e7d
If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents:
2600
diff
changeset
|
562 |
@RunInMain |
19dc6b830e7d
If call to GetPLCstatus can't be executed in PLC, then obtained status is disconnected. Status on "None" is not relevant anymore, and is replaced by Disconnected.
Edouard Tisserant
parents:
2600
diff
changeset
|
563 |
def _GetPLCstatus(self): |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
564 |
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
|
565 |
|
1988
19ca02e8074f
PLCObject got more methods serialized through worker : Start, Stop, NewPLC.
Edouard Tisserant
parents:
1987
diff
changeset
|
566 |
@RunInMain |
2324
1cf3768ebf85
Automatically get PSK and ID when connecting to PYRO[S], so that future connection through PYROS can use that same key. Also fixed case to UPPER for *PSK.
Edouard Tisserant
parents:
2309
diff
changeset
|
567 |
def GetPLCID(self): |
2492
7dd551ac2fa0
check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2487
diff
changeset
|
568 |
return getPSKID(partial(self.LogMessage, 0)) |
2324
1cf3768ebf85
Automatically get PSK and ID when connecting to PYRO[S], so that future connection through PYROS can use that same key. Also fixed case to UPPER for *PSK.
Edouard Tisserant
parents:
2309
diff
changeset
|
569 |
|
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
570 |
def _init_blobs(self): |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
571 |
self.blobs = {} |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
572 |
if os.path.exists(self.tmpdir): |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
573 |
shutil.rmtree(self.tmpdir) |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
574 |
os.mkdir(self.tmpdir) |
2492
7dd551ac2fa0
check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2487
diff
changeset
|
575 |
|
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
576 |
@RunInMain |
2487
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
577 |
def SeedBlob(self, seed): |
2540
fca79ca84272
Replace md5 module with hashlib
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2537
diff
changeset
|
578 |
blob = (mkstemp(dir=self.tmpdir) + (hashlib.new('md5'),)) |
2651
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
579 |
_fd, _path, md5sum = blob |
2487
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
580 |
md5sum.update(seed) |
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
581 |
newBlobID = md5sum.digest() |
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
582 |
self.blobs[newBlobID] = blob |
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
583 |
return newBlobID |
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
584 |
|
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
585 |
@RunInMain |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
586 |
def AppendChunkToBlob(self, data, blobID): |
2487
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
587 |
blob = self.blobs.pop(blobID, None) |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
588 |
|
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
589 |
if blob is None: |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
590 |
return None |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
591 |
|
2651
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
592 |
fd, _path, md5sum = blob |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
593 |
md5sum.update(data) |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
594 |
newBlobID = md5sum.digest() |
2651
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
595 |
os.write(fd, data) |
2487
6a4f9a061994
Reworked chunk based transfer to support duplicated files (i.e. files with same content, but different names)
Edouard Tisserant
parents:
2486
diff
changeset
|
596 |
self.blobs[newBlobID] = blob |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
597 |
return newBlobID |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
598 |
|
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
599 |
@RunInMain |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
600 |
def PurgeBlobs(self): |
2651
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
601 |
for fd, _path, _md5sum in self.blobs.values(): |
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
602 |
os.close(fd) |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
603 |
self._init_blobs() |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
604 |
|
2702
f0a70f0246da
Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents:
2698
diff
changeset
|
605 |
def BlobAsFile(self, blobID, newpath): |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
606 |
blob = self.blobs.pop(blobID, None) |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
607 |
|
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
608 |
if blob is None: |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
609 |
raise Exception(_("Missing data to create file: {}").format(newpath)) |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
610 |
|
2702
f0a70f0246da
Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents:
2698
diff
changeset
|
611 |
self._BlobAsFile(blob, newpath) |
f0a70f0246da
Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents:
2698
diff
changeset
|
612 |
|
f0a70f0246da
Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents:
2698
diff
changeset
|
613 |
def _BlobAsFile(self, blob, newpath): |
2651
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
614 |
fd, path, _md5sum = blob |
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
615 |
fobj = os.fdopen(fd) |
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
616 |
fobj.flush() |
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
617 |
os.fsync(fd) |
231f8bd2cd7d
Runtime: fsync() files when transfering them, to prebent data loss when poweroff soon after programming. Fixed variable naming as a side effect.
Edouard Tisserant
parents:
2646
diff
changeset
|
618 |
fobj.close() |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
619 |
shutil.move(path, newpath) |
2492
7dd551ac2fa0
check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2487
diff
changeset
|
620 |
|
2594
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
621 |
def _extra_files_log_path(self): |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
622 |
return os.path.join(self.workingdir, "extra_files.txt") |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
623 |
|
2596
779e8dbf1ee1
Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents:
2594
diff
changeset
|
624 |
def RepairPLC(self): |
779e8dbf1ee1
Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents:
2594
diff
changeset
|
625 |
self.PurgePLC() |
779e8dbf1ee1
Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents:
2594
diff
changeset
|
626 |
MainWorker.quit() |
779e8dbf1ee1
Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents:
2594
diff
changeset
|
627 |
|
2594
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
628 |
@RunInMain |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
629 |
def PurgePLC(self): |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
630 |
|
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
631 |
extra_files_log = self._extra_files_log_path() |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
632 |
|
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
633 |
old_PLC_filename = os.path.join(self.workingdir, self.CurrentPLCFilename) \ |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
634 |
if self.CurrentPLCFilename is not None \ |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
635 |
else None |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
636 |
|
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
637 |
try: |
2613
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
638 |
allfiles = open(extra_files_log, "rt").readlines() |
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
639 |
allfiles.extend([extra_files_log, old_PLC_filename, self._GetMD5FileName()]) |
2594
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
640 |
except Exception: |
2613
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
641 |
self.LogMessage("No files to purge") |
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
642 |
allfiles = [] |
2594
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
643 |
|
2596
779e8dbf1ee1
Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents:
2594
diff
changeset
|
644 |
for filename in allfiles: |
2613
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
645 |
if filename: |
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
646 |
filename = filename.strip() |
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
647 |
try: |
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
648 |
os.remove(os.path.join(self.workingdir, filename)) |
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
649 |
except Exception: |
e05458405ff4
Fix PLCObject's purge failing silently with extra_files.
Edouard Tisserant
parents:
2612
diff
changeset
|
650 |
self.LogMessage("Couldn't purge " + filename) |
2596
779e8dbf1ee1
Added RepairPLC() to PLCObject. For now just calling PurgePLC and quit PLC runtime.
Edouard Tisserant
parents:
2594
diff
changeset
|
651 |
|
2594
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
652 |
self.PLCStatus = PlcStatus.Empty |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
653 |
|
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
654 |
# TODO: PLCObject restart |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
655 |
|
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
656 |
@RunInMain |
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
657 |
def NewPLC(self, md5sum, plc_object, extrafiles): |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
658 |
if self.PLCStatus in [PlcStatus.Stopped, PlcStatus.Empty, PlcStatus.Broken]: |
229 | 659 |
NewFileName = md5sum + lib_ext |
2594
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
660 |
extra_files_log = self._extra_files_log_path() |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
661 |
|
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
662 |
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
|
663 |
|
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
664 |
self.UnLoadPLC() |
1045
a220a27defe5
Runtime now unloads and cleanup PLC before exit (created threads was preventing exit)
Edouard Tisserant
parents:
1035
diff
changeset
|
665 |
|
2594
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
666 |
self.PurgePLC() |
f1e182818434
Added PurgePLC() method to PLCObject, to be invoked when PLC Status is broken. It clears PLC shared object an extra files and force status to Empty. Added correponding Repair button to toolbar, visible only when PLC status is broken.
Edouard Tisserant
parents:
2586
diff
changeset
|
667 |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1732
diff
changeset
|
668 |
self.LogMessage("NewPLC (%s)" % 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
|
669 |
|
229 | 670 |
try: |
671 |
# Create new PLC file |
|
2702
f0a70f0246da
Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents:
2698
diff
changeset
|
672 |
self.BlobAsFile(plc_object, new_PLC_filename) |
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
|
673 |
|
229 | 674 |
# Then write the files |
2442
b13f021c68a5
python3 support: pylint, W1607 # (file-builtin) file built-in referenced
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2432
diff
changeset
|
675 |
log = open(extra_files_log, "w") |
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
676 |
for fname, blobID in extrafiles: |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
677 |
fpath = os.path.join(self.workingdir, fname) |
2702
f0a70f0246da
Runtime: change PLCObject 'BlobAsFile' method to allow customization by overriding
Edouard Tisserant
parents:
2698
diff
changeset
|
678 |
self.BlobAsFile(blobID, fpath) |
229 | 679 |
log.write(fname+'\n') |
680 |
||
2653
8b612b357679
Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents:
2651
diff
changeset
|
681 |
# Store new PLC filename based on md5 key |
8b612b357679
Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents:
2651
diff
changeset
|
682 |
with open(self._GetMD5FileName(), "w") as f: |
8b612b357679
Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents:
2651
diff
changeset
|
683 |
f.write(md5sum) |
8b612b357679
Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents:
2651
diff
changeset
|
684 |
f.flush() |
8b612b357679
Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents:
2651
diff
changeset
|
685 |
os.fsync(f.fileno()) |
8b612b357679
Runtime: create .md5 file at the end of all transfered files being written to disk, so that it presence indicates completeness of transfer.
Edouard Tisserant
parents:
2651
diff
changeset
|
686 |
|
229 | 687 |
# Store new PLC filename |
688 |
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
|
689 |
except Exception: |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
690 |
self.PLCStatus = 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
|
691 |
self.StatusChange() |
291
701c0601db02
Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents:
290
diff
changeset
|
692 |
PLCprint(traceback.format_exc()) |
229 | 693 |
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
|
694 |
|
2463
8742337a9fe3
Chunk based transfer for PLC binary and extra files, and some collateral code refactoring.
Edouard Tisserant
parents:
2459
diff
changeset
|
695 |
if self.LoadPLC(): |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
696 |
self.PLCStatus = PlcStatus.Stopped |
3282
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
697 |
self.StatusChange() |
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
|
698 |
else: |
3282
725d3e9ac913
Runtime: Handle errors in user's python code more gracefully : make exceptions and allow repair.
Edouard Tisserant
parents:
2732
diff
changeset
|
699 |
self._fail(_("Problem installing new PLC : can't load PLC")) |
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
|
700 |
|
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
701 |
return self.PLCStatus == PlcStatus.Stopped |
229 | 702 |
return False |
703 |
||
704 |
def MatchMD5(self, MD5): |
|
705 |
try: |
|
706 |
last_md5 = open(self._GetMD5FileName(), "r").read() |
|
707 |
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
|
708 |
except Exception: |
1440
e8daabf2c438
Runtime : Added PLCobject methods registring. IDE : Added WAMP connector. Still need some fixes
Edouard Tisserant
parents:
1438
diff
changeset
|
709 |
pass |
e8daabf2c438
Runtime : Added PLCobject methods registring. IDE : Added WAMP connector. Still need some fixes
Edouard Tisserant
parents:
1438
diff
changeset
|
710 |
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
|
711 |
|
2485
ef327451d067
Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents:
2463
diff
changeset
|
712 |
@RunInMain |
229 | 713 |
def SetTraceVariablesList(self, idxs): |
714 |
""" |
|
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
|
715 |
Call ctype imported function to append |
229 | 716 |
these indexes to registred variables in PLC debugger |
717 |
""" |
|
2485
ef327451d067
Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents:
2463
diff
changeset
|
718 |
self.DebugToken += 1 |
462
274e83a5534e
Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
461
diff
changeset
|
719 |
if idxs: |
274e83a5534e
Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
461
diff
changeset
|
720 |
# suspend but dont disable |
614 | 721 |
if self._suspendDebug(False) == 0: |
722 |
# keep a copy of requested idx |
|
723 |
self._ResetDebugVariables() |
|
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
724 |
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
|
725 |
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
|
726 |
c_type, _unpack_func, pack_func = \ |
614 | 727 |
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
|
728 |
(None, None, None)) |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
729 |
force = ctypes.byref(pack_func(c_type, force)) |
3395
93ad018fb602
RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents:
3282
diff
changeset
|
730 |
res = self._RegisterDebugVariable(idx, force) |
93ad018fb602
RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents:
3282
diff
changeset
|
731 |
if res != 0: |
93ad018fb602
RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents:
3282
diff
changeset
|
732 |
self._resumeDebug() |
93ad018fb602
RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents:
3282
diff
changeset
|
733 |
self._suspendDebug(True) |
93ad018fb602
RUNTIME: Variable forcing now uses limited list and buffer instead of systematical instance tree traversal and in-tree "fvalue" to keep track of forced value for pointed variables (external, located). Pointer swapping is performed when forcing externals and located, with backup being restored when forcing is reset. Retain still uses tree traversal.
Edouard Tisserant
parents:
3282
diff
changeset
|
734 |
return -res |
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
|
735 |
self._TracesSwap() |
614 | 736 |
self._resumeDebug() |
2485
ef327451d067
Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents:
2463
diff
changeset
|
737 |
return self.DebugToken |
462
274e83a5534e
Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
461
diff
changeset
|
738 |
else: |
274e83a5534e
Now debug is not a button anymore
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
461
diff
changeset
|
739 |
self._suspendDebug(True) |
3577
6c7a7b22bec9
IDE+Runtime: fix exception when reconnecting with non-empty trace/force list.
Edouard Tisserant
parents:
3395
diff
changeset
|
740 |
return 4 # DEBUG_SUSPENDED |
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
|
741 |
|
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
|
742 |
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
|
743 |
self.LastSwapTrace = time() |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
744 |
if self.TraceThread is None and self.PLCStatus == PlcStatus.Started: |
2600
0e20a0d48fae
Named runtime's threads to ease debugging
Edouard Tisserant
parents:
2596
diff
changeset
|
745 |
self.TraceThread = Thread(target=self.TraceThreadProc, name="PLCTrace") |
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
|
746 |
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
|
747 |
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
|
748 |
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
|
749 |
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
|
750 |
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
|
751 |
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
|
752 |
|
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
753 |
@RunInMain |
2485
ef327451d067
Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents:
2463
diff
changeset
|
754 |
def GetTraceVariables(self, DebugToken): |
2546
f5dae7b85906
Fix pylint warning [C0325(superfluous-parens), ] Unnecessary parens after u'if' keyword
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2540
diff
changeset
|
755 |
if DebugToken is not None and DebugToken == self.DebugToken: |
2485
ef327451d067
Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents:
2463
diff
changeset
|
756 |
return self.PLCStatus, self._TracesSwap() |
ef327451d067
Add a debugger token to SetTraceVariables and GetTraceVariables to prevent crash an inconsistant data in case of multiple connections. Last connection now takes over existing connections's debug, and first connected IDE gets a wrning.
Edouard Tisserant
parents:
2463
diff
changeset
|
757 |
return PlcStatus.Broken, [] |
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
|
758 |
|
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
|
759 |
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
|
760 |
""" |
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
|
761 |
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
|
762 |
""" |
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
763 |
self._resumeDebug() # Re-enable debugger |
2416
1ca207782dde
Use predefined constants for PlcStatus instead of string literals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1997
diff
changeset
|
764 |
while self.PLCStatus == PlcStatus.Started: |
450
18583d13f0fa
Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
446
diff
changeset
|
765 |
tick = ctypes.c_uint32() |
18583d13f0fa
Preliminary accessor support for debug
Edouard TISSERANT <edouard.tisserant@gmail.com>
parents:
446
diff
changeset
|
766 |
size = ctypes.c_uint32() |
1075
8078c01ae464
Now Debug Buffer Unpacking is a separate function, declared in typemapping.py
Edouard Tisserant
parents:
1074
diff
changeset
|
767 |
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
|
768 |
TraceBuffer = None |
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
769 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
770 |
self.PLClibraryLock.acquire() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
771 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
772 |
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
|
773 |
ctypes.byref(size), |
1997 | 774 |
ctypes.byref(buff)) |
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
775 |
if res == 0: |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
776 |
if size.value: |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
777 |
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
|
778 |
self._FreeDebugData() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
779 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
780 |
self.PLClibraryLock.release() |
1997 | 781 |
|
1994
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
782 |
# 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
|
783 |
if res != 0: |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
784 |
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
|
785 |
|
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
|
786 |
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
|
787 |
self.TraceLock.acquire() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
788 |
lT = len(self.Traces) |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
789 |
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
|
790 |
self.Traces.pop(0) |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
791 |
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
|
792 |
self.TraceLock.release() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
793 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
794 |
# 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
|
795 |
traces_age = time() - self.LastSwapTrace |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
796 |
if traces_age > 3: |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
797 |
self.TraceLock.acquire() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
798 |
self.Traces = [] |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
799 |
self.TraceLock.release() |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
800 |
self._suspendDebug(True) # Disable debugger |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
801 |
break |
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
802 |
|
1fdc32be71b8
Rework of runtime non-real-time threading, and shared object dynamic loading :
Edouard Tisserant
parents:
1993
diff
changeset
|
803 |
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
|
804 |
|
1440
e8daabf2c438
Runtime : Added PLCobject methods registring. IDE : Added WAMP connector. Still need some fixes
Edouard Tisserant
parents:
1438
diff
changeset
|
805 |
def RemoteExec(self, script, *kwargs): |
699
6ff64cadb1ff
Adding support for executing python scripts on remote runtime
laurent
parents:
690
diff
changeset
|
806 |
try: |
2419
c081dabc0f63
Fix old style exception raise and exec syntax
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2418
diff
changeset
|
807 |
exec(script, kwargs) |
1780
c52d1460cea8
clean-up: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1768
diff
changeset
|
808 |
except Exception: |
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
809 |
_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
|
810 |
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
|
811 |
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
|
812 |
(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
|
813 |
return (0, kwargs.get("returnVal", None)) |