Fixed Xenomai 3 PLC stop freeze. Now use explicit finish command with pipes. Closing both ends of pipes doesn't abort blocking read anymore.
--- a/runtime/PLCObject.py Mon Apr 16 11:00:04 2018 +0200
+++ b/runtime/PLCObject.py Mon Apr 16 16:11:18 2018 +0200
@@ -459,10 +459,8 @@
res, cmd, blkid = "None", "None", ctypes.c_void_p()
compile_cache = {}
while True:
- # print "_PythonIterator(", res, ")",
cmd = self._PythonIterator(res, blkid)
FBID = blkid.value
- # print " -> ", cmd, blkid
if cmd is None:
break
try:
@@ -655,13 +653,18 @@
buff = ctypes.c_void_p()
TraceBuffer = None
if self.PLClibraryLock.acquire(False):
- if self._GetDebugData(ctypes.byref(tick),
- ctypes.byref(size),
- ctypes.byref(buff)) == 0:
+ res = self._GetDebugData(ctypes.byref(tick),
+ ctypes.byref(size),
+ ctypes.byref(buff))
+ if res == 0:
if size.value:
TraceBuffer = ctypes.string_at(buff.value, size.value)
self._FreeDebugData()
self.PLClibraryLock.release()
+
+ if res != 0:
+ break
+
if TraceBuffer is not None:
self._TracesPush((tick.value, TraceBuffer))
self._TracesAutoSuspend()
--- a/targets/Xenomai/plc_Xenomai_main.c Mon Apr 16 11:00:04 2018 +0200
+++ b/targets/Xenomai/plc_Xenomai_main.c Mon Apr 16 16:11:18 2018 +0200
@@ -37,6 +37,15 @@
#define PYTHON_PIPE_MINOR 3
#define PIPE_SIZE 1
+// rt-pipes commands
+
+#define PYTHON_PENDING_COMMAND 1
+#define PYTHON_FINISH 2
+
+#define DEBUG_FINISH 2
+
+#define DEBUG_PENDING_DATA 1
+#define DEBUG_UNLOCK 1
long AtomicCompareExchange(long* atomicvar,long compared, long exchange)
{
@@ -82,6 +91,18 @@
if (PLC_shutdown) break;
rt_task_wait_period(NULL);
}
+ /* since xenomai 3 it is not enough to close()
+ file descriptor to unblock read()... */
+ {
+ /* explicitely finish python thread */
+ char msg = PYTHON_FINISH;
+ rt_pipe_write(&WaitPython_pipe, &msg, sizeof(msg), P_NORMAL);
+ }
+ {
+ /* explicitely finish debug thread */
+ char msg = DEBUG_FINISH;
+ rt_pipe_write(&WaitDebug_pipe, &msg, sizeof(msg), P_NORMAL);
+ }
}
static unsigned long __debug_tick;
@@ -256,7 +277,6 @@
return 0;
}
-#define DEBUG_UNLOCK 1
void LeaveDebugSection(void)
{
if(AtomicCompareExchange( &debug_state,
@@ -269,7 +289,6 @@
extern unsigned long __tick;
-#define DEBUG_PENDING_DATA 1
int WaitDebugData(unsigned long *tick)
{
char cmd;
@@ -319,8 +338,6 @@
AtomicCompareExchange( &debug_state, DEBUG_BUSY, DEBUG_FREE);
}
-#define PYTHON_PENDING_COMMAND 1
-
#define PYTHON_FREE 0
#define PYTHON_BUSY 1
static long python_state = PYTHON_FREE;