From a6486909ca2d20094fdbd60e9045901a77d67833 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 13 Mar 2023 17:31:35 +0100 Subject: [PATCH] Reimplement itti_wait_tasks_end() to allow custom wait handlers In the UE, we wish to handle ^C in the UE to send a message before terminating, so we allow custom wait handlers to implement such functionality. Use itti_wait_tasks_unblock() to unblock itti_wait_tasks_end(). Also, implement itti_wait_tasks_end() using semaphores, as signals are not async-signal-safe (and therefore should not be used in a signal handler). --- common/utils/ocp_itti/intertask_interface.cpp | 27 ++++++++++++------- common/utils/ocp_itti/intertask_interface.h | 9 ++++--- executables/lte-softmodem.c | 2 +- executables/lte-uesoftmodem.c | 2 +- executables/nr-cuup.c | 2 +- executables/nr-softmodem.c | 2 +- executables/nr-uesoftmodem.c | 2 +- 7 files changed, 29 insertions(+), 17 deletions(-) diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index fe43dde319..897e6757af 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -24,6 +24,7 @@ #include #include #include +#include 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) { + 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)); - pthread_mutex_init(&signal_mutex, NULL); - pthread_mutex_lock(&signal_mutex); + if (handler == NULL) /* no handler given: install default */ + handler = catch_sigterm; + signal(SIGTERM, handler); + signal(SIGINT, handler); - signal(SIGTERM, catch_sigterm); - signal(SIGINT, catch_sigterm); - - 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 3874d52829..19b0ba32a9 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 6d75f0acbd..f4f62f9a08 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 4fe94f0b80..8e0161c1b6 100644 --- a/executables/lte-uesoftmodem.c +++ b/executables/lte-uesoftmodem.c @@ -699,7 +699,7 @@ int main( int argc, char **argv ) { printf("TYPE 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 25ebe6df13..72430b5c3a 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 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 120a7c0e65..820173dc97 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 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 bb439ff4f0..9611325edd 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 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);