modbus/mb_runtime.c
changeset 2688 4dd67aa45855
parent 2687 c79c5d49ba34
child 2716 ebb2595504f0
--- a/modbus/mb_runtime.c	Thu Aug 13 18:42:02 2020 +0100
+++ b/modbus/mb_runtime.c	Thu Aug 13 19:00:38 2020 +0100
@@ -436,46 +436,6 @@
 
 
 
-/* Function to activate a client node's thread */
-/* returns -1 if it could not send the signal */
-static int __signal_client_thread(int client_node_id) {
-    /* We TRY to signal the client thread.
-     * We do this because this function can be called at the end of the PLC scan cycle
-     * and we don't want it to block at that time.
-     */
-    if (pthread_mutex_trylock(&(client_nodes[client_node_id].mutex)) != 0)
-        return -1;
-    client_nodes[client_node_id].execute_req = 1; // tell the thread to execute
-    pthread_cond_signal (&(client_nodes[client_node_id].condv));
-    pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
-    return 0;
-}
-
-
-
-/* Function that will be called whenever a client node's periodic timer expires. */
-/* The client node's thread will be waiting on a condition variable, so this function simply signals that 
- * condition variable.
- * 
- * The same callback function is called by the timers of all client nodes. The id of the client node
- * in question will be passed as a parameter to the call back function.
- */
-void __client_node_timer_callback_function(int client_node_id) {
-    /* signal the client node's condition variable on which the client node's thread should be waiting... */
-    /* Since the communication cycle is run with the mutex locked, we use trylock() instead of lock() */
-    if (pthread_mutex_trylock (&(client_nodes[client_node_id].mutex)) != 0)
-        /* we never get to signal the thread for activation. But that is OK.
-         * If it still in the communication cycle (during which the mutex is kept locked)
-         * then that means that the communication cycle is falling behing in the periodic 
-         * communication cycle, and we therefore need to skip a period.
-         */
-        return;
-    client_nodes[client_node_id].execute_req  = 1; // tell the thread to execute
-    client_nodes[client_node_id].periodic_act = 1; // tell the thread the activation was done by periodic timer   
-    pthread_cond_signal (&(client_nodes[client_node_id].condv));
-    pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
-}
-
 
 
 /* Thread that simply implements a periodic 'timer',
@@ -528,10 +488,24 @@
         }
         
         while (0 != clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_cycle, NULL));
-        __client_node_timer_callback_function(client_node_id);
+        
+        /* signal the client node's condition variable on which the client node's thread should be waiting... */
+        /* Since the communication cycle is run with the mutex locked, we use trylock() instead of lock() */
+        if (pthread_mutex_trylock (&(client_nodes[client_node_id].mutex)) == 0) {
+            client_nodes[client_node_id].execute_req  = 1; // tell the thread to execute
+            client_nodes[client_node_id].periodic_act = 1; // tell the thread the activation was done by periodic timer   
+            pthread_cond_signal (&(client_nodes[client_node_id].condv));
+            pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
+        } else {
+            /* We never get to signal the thread for activation. But that is OK.
+             * If it still in the communication cycle (during which the mutex is kept locked)
+             * then that means that the communication cycle is falling behing in the periodic 
+             * communication cycle, and we therefore need to skip a period.
+             */
+        }
     }
 
-    return NULL;
+    return NULL; // humour the compiler -> will never be executed!
 }
 
 
@@ -743,13 +717,26 @@
          */
         if ((client_requests[index].flag_exec_req != 0) && (0 == client_requests[index].flag_exec_started)) {
             int client_node_id = client_requests[index].client_node_id;
-            if (__signal_client_thread(client_node_id) >= 0) {
-                /* - upon success, set flag_exec_started
-                 * - both flags (flag_exec_req and flag_exec_started) will be reset
-                 *   once the transaction has completed.
-                 */
-                client_requests[index].flag_exec_started = 1;    
-            }
+            
+             /* We TRY to signal the client thread.
+              * We do this because this function can be called at the end of the PLC scan cycle
+              * and we don't want it to block at that time.
+              */
+             if (pthread_mutex_trylock(&(client_nodes[client_node_id].mutex)) == 0) {
+                 client_nodes[client_node_id].execute_req = 1; // tell the thread to execute
+                 pthread_cond_signal (&(client_nodes[client_node_id].condv));
+                 pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
+                 /* - upon success, set flag_exec_started
+                  * - both flags (flag_exec_req and flag_exec_started) will be reset
+                  *   once the transaction has completed.
+                  */
+                 client_requests[index].flag_exec_started = 1;    
+             } else {
+                 /* The mutex is locked => the client thread is currently executing MB transactions.
+                  * We will try to activate it in the next PLC cycle...
+                  * For now, do nothing.
+                  */
+             }
         }                    
     }
 }