From f00c0363674c200a15722fb41c95281f2bc4ce93 Mon Sep 17 00:00:00 2001
From: winckel <winckel@eurecom.fr>
Date: Wed, 23 Oct 2013 14:08:42 +0000
Subject: [PATCH] added "itti_exit_task" to terminate current task when a
 MESSAGE_TERMINATE is received. Modified "itti_wait_tasks_end" to exit when
 some threads are not terminated after a 1 second time-out. modified "SIGINT"
 handling, exit is done after tring to join all threads like for "SIGUSR1".
 Added message reception for TASK_L2L1 and handling of TEST and TERMINATE
 messages in oaisim.

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4269 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 common/utils/itti/intertask_interface.c | 41 +++++++++++++++++++++----
 common/utils/itti/intertask_interface.h |  4 +++
 common/utils/itti/signals.c             |  8 +++--
 targets/SIMU/USER/oaisim.c              | 28 +++++++++++++++--
 4 files changed, 70 insertions(+), 11 deletions(-)

diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c
index 53b8101dbb..1780a9b967 100644
--- a/common/utils/itti/intertask_interface.c
+++ b/common/utils/itti/intertask_interface.c
@@ -28,6 +28,7 @@
 
  *******************************************************************************/
 
+#define _GNU_SOURCE
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -394,6 +395,10 @@ void itti_mark_task_ready(task_id_t task_id) {
     pthread_mutex_unlock (&itti_desc.tasks[thread_id].message_queue_mutex);
 }
 
+void itti_exit_task(void) {
+    pthread_exit (NULL);
+}
+
 void itti_terminate_tasks(task_id_t task_id) {
     // Sends Terminate signals to all tasks.
     itti_send_terminate_message (task_id);
@@ -442,6 +447,9 @@ int itti_init(thread_id_t thread_max, MessagesIds messages_id_max, const char *
 void itti_wait_tasks_end(void) {
     int end = 0;
     int i;
+    int ready_tasks;
+    int result;
+    int retries = 10;
 
     itti_desc.thread_handling_signals = pthread_self ();
 
@@ -450,14 +458,35 @@ void itti_wait_tasks_end(void) {
         signal_handle (&end);
     }
 
-    for (i = THREAD_FIRST; i < itti_desc.thread_max; i++) {
-        /* Skip tasks which are not running */
-        if (itti_desc.tasks[i].task_state == TASK_STATE_READY) {
-            ITTI_DEBUG("Waiting end of thread %s\n", itti_desc.threads_name[i]);
+    do {
+        ready_tasks = 0;
+
+        for (i = THREAD_FIRST; i < itti_desc.thread_max; i++) {
+            /* Skip tasks which are not running */
+            if (itti_desc.tasks[i].task_state == TASK_STATE_READY) {
 
-            pthread_join (itti_desc.tasks[i].task_thread, NULL);
-            itti_desc.tasks[i].task_state = TASK_STATE_ENDED;
+                result = pthread_tryjoin_np (itti_desc.tasks[i].task_thread, NULL);
+
+                ITTI_DEBUG("Thread %s join status %d\n", itti_desc.threads_name[i], result);
+
+                if (result == 0) {
+                    /* Thread has terminated */
+                    itti_desc.tasks[i].task_state = TASK_STATE_ENDED;
+                }
+                else {
+                    /* Thread is still running, count it */
+                    ready_tasks++;
+                }
+            }
+        }
+        if (ready_tasks > 0) {
+            usleep (100 * 1000);
         }
+    } while ((ready_tasks > 0) && (retries--));
+
+    if (ready_tasks > 0) {
+        ITTI_DEBUG("Some threads are still running, force exit\n");
+        exit (0);
     }
 }
 
diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h
index 9b1ac0851a..7856cee9ef 100644
--- a/common/utils/itti/intertask_interface.h
+++ b/common/utils/itti/intertask_interface.h
@@ -120,6 +120,10 @@ int itti_create_task(task_id_t task_id,
  **/
 void itti_mark_task_ready(task_id_t task_id);
 
+/** \brief Exit the current task.
+ **/
+void itti_exit_task(void);
+
 /** \brief Indicate that the task is completed and initiate termination of all tasks.
  * \param task_id task that is completed
  **/
diff --git a/common/utils/itti/signals.c b/common/utils/itti/signals.c
index 1fc62fc0a4..0f5c4e7415 100644
--- a/common/utils/itti/signals.c
+++ b/common/utils/itti/signals.c
@@ -60,6 +60,7 @@ int signal_init(void)
     sigemptyset(&set);
 
     sigaddset (&set, SIGTIMER);
+    sigaddset (&set, SIGUSR1);
     sigaddset (&set, SIGABRT);
     sigaddset (&set, SIGSEGV);
     sigaddset (&set, SIGINT);
@@ -115,18 +116,19 @@ int signal_handle(int *end)
                 printf("Received SIGUSR1\n");
                 *end = 1;
                 break;
+
             case SIGSEGV:   /* Fall through */
             case SIGABRT:
                 printf("Received SIGABORT\n");
                 backtrace_handle_signal(&info);
                 break;
-            case SIGQUIT:
+
             case SIGINT:
                 printf("Received SIGINT\n");
                 itti_send_terminate_message(TASK_UNKNOWN);
-                printf("All tasks terminated -> exiting '"PACKAGE_NAME"'\n");
-                exit(0);
+                *end = 1;
                 break;
+
             default:
                 printf("Received unknown signal %d\n", info.si_signo);
                 break;
diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c
index f96bed6f78..73cdf67bee 100644
--- a/targets/SIMU/USER/oaisim.c
+++ b/targets/SIMU/USER/oaisim.c
@@ -376,14 +376,13 @@ void *l2l1_task(void *args_p) {
   char fname[64], vname[64];
 
 #if defined(ENABLE_ITTI)
+  MessageDef *message_p;
   long timer_id;
 
   itti_mark_task_ready(TASK_L2L1);
 
   /* Test code */
   {
-    MessageDef *message_p;
-
     message_p = itti_alloc_new_message(TASK_L2L1, MESSAGE_TEST);
 
     itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, message_p);
@@ -400,6 +399,31 @@ void *l2l1_task(void *args_p) {
 #endif
 
   for (frame = 0; frame < oai_emulation.info.n_frames; frame++) {
+#if defined(ENABLE_ITTI)
+    // Checks if a message has been sent to L2L1 task
+    itti_poll_msg(TASK_L2L1, INSTANCE_ALL, &message_p);
+
+    if(message_p != NULL)
+    {
+      switch(message_p->header.messageId)
+      {
+        case TERMINATE_MESSAGE:
+          itti_exit_task();
+          break;
+
+        case MESSAGE_TEST:
+          LOG_D(EMU, "Received %s\n", itti_get_message_name(message_p->header.messageId));
+          break;
+
+        default:
+          LOG_E(EMU, "Received unexpected message %s\n", itti_get_message_name(message_p->header.messageId));
+          break;
+      }
+
+      free(message_p);
+    }
+#endif
+
     /*
      // Handling the cooperation Flag
      if (cooperation_flag == 2)
-- 
GitLab