diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp
index fe43dde3193afe2daef09415d02167b929e3a234..897e6757afa57434ae4eed6d82088648f23da3ff 100644
--- a/common/utils/ocp_itti/intertask_interface.cpp
+++ b/common/utils/ocp_itti/intertask_interface.cpp
@@ -24,6 +24,7 @@
 #include <vector>
 #include <map>
 #include <sys/eventfd.h>
+#include <semaphore.h>
 
 
 extern "C" {
@@ -434,24 +435,32 @@ extern "C" {
   void itti_send_terminate_message(task_id_t task_id) {
   }
 
-  pthread_mutex_t signal_mutex;
+  sem_t itti_sem_block;
+  void itti_wait_tasks_unblock()
+  {
+    int rc = sem_post(&itti_sem_block);
+    AssertFatal(rc == 0, "error in sem_post(): %d %s\n", errno, strerror(errno));
+  }
 
   static void catch_sigterm(int) {
     static const char msg[] = "\n** Caught SIGTERM, shutting down\n";
     __attribute__((unused))
     int unused = write(STDOUT_FILENO, msg, sizeof(msg) - 1);
-    pthread_mutex_unlock(&signal_mutex);
+    itti_wait_tasks_unblock();
   }
 
-  void itti_wait_tasks_end(void) {
-
-    pthread_mutex_init(&signal_mutex, NULL);
-    pthread_mutex_lock(&signal_mutex);
+  void itti_wait_tasks_end(void (*handler)(int))
+  {
+    int rc = sem_init(&itti_sem_block, 0, 0);
+    AssertFatal(rc == 0, "error in sem_init(): %d %s\n", errno, strerror(errno));
 
-    signal(SIGTERM, catch_sigterm);
-    signal(SIGINT, catch_sigterm);
+    if (handler == NULL) /* no handler given: install default */
+      handler = catch_sigterm;
+    signal(SIGTERM, handler);
+    signal(SIGINT, handler);
 
-    pthread_mutex_lock(&signal_mutex);
+    rc = sem_wait(&itti_sem_block);
+    AssertFatal(rc == 0, "error in sem_wait(): %d %s\n", errno, strerror(errno));
   }
 
   void itti_update_lte_time(uint32_t frame, uint8_t slot) {}
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 3874d5282973cb66717a5be895080615972afefb..19b0ba32a9611177fc61987c6cd55027e3001a4a 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -550,10 +550,13 @@ MessageDef *itti_alloc_new_message_sized(
   MessagesIds       message_id,
   MessageHeaderSize size);
 
-/** \brief handle signals and wait for all threads to join when the process complete.
-   This function should be called from the main thread after having created all ITTI tasks.
+/** \brief Wait for SIGINT/SIGTERM signals to unblock ITTI.
+   This function should be called from the main thread after having created all ITTI tasks. If handler is NULL, a default handler is installed.
+    \param handler a custom signal handler. To unblock, it should call itti_wait_tasks_unblock()
  **/
-void itti_wait_tasks_end(void);
+void itti_wait_tasks_end(void (*handler)(int));
+/** \brif unblocks ITTI waiting in itti_wait_tasks_end(). **/
+void itti_wait_tasks_unblock(void);
 void itti_set_task_real_time(task_id_t task_id);
 
 /** \brief Send a termination message to all tasks.
diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c
index 6d75f0acbd7d758944aaf3a8f7ec652072a4b752..f4f62f9a08eef7531458de0fb82af4a60c682ddc 100644
--- a/executables/lte-softmodem.c
+++ b/executables/lte-softmodem.c
@@ -614,7 +614,7 @@ int main ( int argc, char **argv )
   //getchar();
   if(IS_SOFTMODEM_DOSCOPE)
      load_softscope("enb",NULL);
-  itti_wait_tasks_end();
+  itti_wait_tasks_end(NULL);
 
 #if USING_GPROF
   // Save the gprof data now (rather than via atexit) in case we crash while shutting down
diff --git a/executables/lte-uesoftmodem.c b/executables/lte-uesoftmodem.c
index 4fe94f0b8052020b64955fd197cd5e801bd480d3..8e0161c1b63133d488a9681169a2faf07d52041c 100644
--- a/executables/lte-uesoftmodem.c
+++ b/executables/lte-uesoftmodem.c
@@ -699,7 +699,7 @@ int main( int argc, char **argv ) {
   printf("TYPE <CTRL-C> TO TERMINATE\n");
   //getchar();
   printf("Entering ITTI signals handler\n");
-  itti_wait_tasks_end();
+  itti_wait_tasks_end(NULL);
   printf("Returned from ITTI signal handler\n");
   oai_exit=1;
   printf("oai_exit=%d\n",oai_exit);
diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c
index 25ebe6df135b74af7a4ab024d0debc7b27d8e73f..72430b5c3af951ce4b1a7f1dc652b9156b4f53a7 100644
--- a/executables/nr-cuup.c
+++ b/executables/nr-cuup.c
@@ -153,7 +153,7 @@ int main(int argc, char **argv)
   itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);
 
   printf("TYPE <CTRL-C> TO TERMINATE\n");
-  itti_wait_tasks_end();
+  itti_wait_tasks_end(NULL);
 
   logClean();
   printf("Bye.\n");
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 120a7c0e65ddb5cc08bedad662cf12ab47602473..820173dc978891fae258c0aa972268c7fe4b10fe 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -733,7 +733,7 @@ int main( int argc, char **argv ) {
   // wait for end of program
   printf("Entering ITTI signals handler\n");
   printf("TYPE <CTRL-C> TO TERMINATE\n");
-  itti_wait_tasks_end();
+  itti_wait_tasks_end(NULL);
   printf("Returned from ITTI signal handler\n");
   oai_exit=1;
   printf("oai_exit=%d\n",oai_exit);
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index bb439ff4f01c4c4f38d191c1ea5bbaebbfdc3321..9611325eddaec27a071487edd3b84f0b291d321e 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -563,7 +563,7 @@ int main( int argc, char **argv ) {
   // wait for end of program
   printf("Entering ITTI signals handler\n");
   printf("TYPE <CTRL-C> TO TERMINATE\n");
-  itti_wait_tasks_end();
+  itti_wait_tasks_end(NULL);
   printf("Returned from ITTI signal handler\n");
   oai_exit=1;
   printf("oai_exit=%d\n",oai_exit);