Fixed Xenomai 3 PLC stop freeze. Now use explicit finish command with pipes. Closing both ends of pipes doesn't abort blocking read anymore.
authorEdouard Tisserant
Mon, 16 Apr 2018 16:11:18 +0200
changeset 1990 2e0fbdd152de
parent 1989 9b5c712f4488
child 1993 cbf0a9ffc782
Fixed Xenomai 3 PLC stop freeze. Now use explicit finish command with pipes. Closing both ends of pipes doesn't abort blocking read anymore.
runtime/PLCObject.py
targets/Xenomai/plc_Xenomai_main.c
--- 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;