Fixed race concerning thread signaling when master thread had no
authorFlorian Pose <fp@igh-essen.com>
Fri, 08 Aug 2008 13:47:23 +0000
changeset 1198 be606e9caba4
parent 1197 f65f9c36ba33
child 1199 30714bab3a04
child 1627 22954d039fa5
child 1768 bfd12f8338e0
Fixed race concerning thread signaling when master thread had no
opportunity to run, but shall be killed immediately.
master/master.c
master/master.h
--- a/master/master.c	Fri Aug 08 13:42:46 2008 +0000
+++ b/master/master.c	Fri Aug 08 13:47:23 2008 +0000
@@ -313,6 +313,7 @@
         int (*thread_func)(ec_master_t *) /**< thread function to start */
         )
 {
+    init_completion(&master->thread_can_terminate);
     init_completion(&master->thread_exit);
 
     EC_INFO("Starting master thread.\n");
@@ -341,11 +342,15 @@
     if (master->debug_level)
         EC_DBG("Stopping master thread.\n");
 
+    // wait until thread is ready to receive the SIGTERM
+    wait_for_completion(&master->thread_can_terminate);
+
     kill_proc(master->thread_id, SIGTERM, 1);
     wait_for_completion(&master->thread_exit);
     EC_INFO("Master thread exited.\n");
 
-    if (master->fsm_datagram.state != EC_DATAGRAM_SENT) return;
+    if (master->fsm_datagram.state != EC_DATAGRAM_SENT)
+        return;
     
     // wait for FSM datagram
     sleep_jiffies = max(HZ / 100, 1); // 10 ms, at least 1 jiffy
@@ -822,6 +827,7 @@
 {
     daemonize("EtherCAT-IDLE");
     allow_signal(SIGTERM);
+    complete(&master->thread_can_terminate);
 
     while (!signal_pending(current)) {
         ec_datagram_output_stats(&master->fsm_datagram);
@@ -869,6 +875,7 @@
 {
     daemonize("EtherCAT-OP");
     allow_signal(SIGTERM);
+    complete(&master->thread_can_terminate);
 
     while (!signal_pending(current)) {
         ec_datagram_output_stats(&master->fsm_datagram);
--- a/master/master.h	Fri Aug 08 13:42:46 2008 +0000
+++ b/master/master.h	Fri Aug 08 13:47:23 2008 +0000
@@ -135,6 +135,13 @@
                                      call to ecrt_master_receive(). */
 
     int thread_id; /**< Master thread PID. */
+    struct completion thread_can_terminate; /**< Thread termination completion
+                                              object. When stopping the
+                                              thread, it must be assured, that
+                                              it 'hears' a SIGTERM, therefore
+                                              the allow_singal() function must
+                                              have been called.
+                                             */
     struct completion thread_exit; /**< Thread completion object. */
 
 #ifdef EC_EOE