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).
This commit is contained in:
Robert Schmidt
2023-03-28 14:12:05 +02:00
parent 4700dde2ae
commit a6486909ca
7 changed files with 29 additions and 17 deletions
+18 -9
View File
@@ -24,6 +24,7 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <sys/eventfd.h> #include <sys/eventfd.h>
#include <semaphore.h>
extern "C" { extern "C" {
@@ -434,24 +435,32 @@ extern "C" {
void itti_send_terminate_message(task_id_t task_id) { 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 void catch_sigterm(int) {
static const char msg[] = "\n** Caught SIGTERM, shutting down\n"; static const char msg[] = "\n** Caught SIGTERM, shutting down\n";
__attribute__((unused)) __attribute__((unused))
int unused = write(STDOUT_FILENO, msg, sizeof(msg) - 1); 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); if (handler == NULL) /* no handler given: install default */
pthread_mutex_lock(&signal_mutex); handler = catch_sigterm;
signal(SIGTERM, handler);
signal(SIGINT, handler);
signal(SIGTERM, catch_sigterm); rc = sem_wait(&itti_sem_block);
signal(SIGINT, catch_sigterm); AssertFatal(rc == 0, "error in sem_wait(): %d %s\n", errno, strerror(errno));
pthread_mutex_lock(&signal_mutex);
} }
void itti_update_lte_time(uint32_t frame, uint8_t slot) {} void itti_update_lte_time(uint32_t frame, uint8_t slot) {}
+6 -3
View File
@@ -550,10 +550,13 @@ MessageDef *itti_alloc_new_message_sized(
MessagesIds message_id, MessagesIds message_id,
MessageHeaderSize size); MessageHeaderSize size);
/** \brief handle signals and wait for all threads to join when the process complete. /** \brief Wait for SIGINT/SIGTERM signals to unblock ITTI.
This function should be called from the main thread after having created all ITTI tasks. 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); void itti_set_task_real_time(task_id_t task_id);
/** \brief Send a termination message to all tasks. /** \brief Send a termination message to all tasks.
+1 -1
View File
@@ -614,7 +614,7 @@ int main ( int argc, char **argv )
//getchar(); //getchar();
if(IS_SOFTMODEM_DOSCOPE) if(IS_SOFTMODEM_DOSCOPE)
load_softscope("enb",NULL); load_softscope("enb",NULL);
itti_wait_tasks_end(); itti_wait_tasks_end(NULL);
#if USING_GPROF #if USING_GPROF
// Save the gprof data now (rather than via atexit) in case we crash while shutting down // Save the gprof data now (rather than via atexit) in case we crash while shutting down
+1 -1
View File
@@ -699,7 +699,7 @@ int main( int argc, char **argv ) {
printf("TYPE <CTRL-C> TO TERMINATE\n"); printf("TYPE <CTRL-C> TO TERMINATE\n");
//getchar(); //getchar();
printf("Entering ITTI signals handler\n"); printf("Entering ITTI signals handler\n");
itti_wait_tasks_end(); itti_wait_tasks_end(NULL);
printf("Returned from ITTI signal handler\n"); printf("Returned from ITTI signal handler\n");
oai_exit=1; oai_exit=1;
printf("oai_exit=%d\n",oai_exit); printf("oai_exit=%d\n",oai_exit);
+1 -1
View File
@@ -153,7 +153,7 @@ int main(int argc, char **argv)
itti_send_msg_to_task(TASK_CUUP_E1, 0, msg); itti_send_msg_to_task(TASK_CUUP_E1, 0, msg);
printf("TYPE <CTRL-C> TO TERMINATE\n"); printf("TYPE <CTRL-C> TO TERMINATE\n");
itti_wait_tasks_end(); itti_wait_tasks_end(NULL);
logClean(); logClean();
printf("Bye.\n"); printf("Bye.\n");
+1 -1
View File
@@ -733,7 +733,7 @@ int main( int argc, char **argv ) {
// wait for end of program // wait for end of program
printf("Entering ITTI signals handler\n"); printf("Entering ITTI signals handler\n");
printf("TYPE <CTRL-C> TO TERMINATE\n"); printf("TYPE <CTRL-C> TO TERMINATE\n");
itti_wait_tasks_end(); itti_wait_tasks_end(NULL);
printf("Returned from ITTI signal handler\n"); printf("Returned from ITTI signal handler\n");
oai_exit=1; oai_exit=1;
printf("oai_exit=%d\n",oai_exit); printf("oai_exit=%d\n",oai_exit);
+1 -1
View File
@@ -563,7 +563,7 @@ int main( int argc, char **argv ) {
// wait for end of program // wait for end of program
printf("Entering ITTI signals handler\n"); printf("Entering ITTI signals handler\n");
printf("TYPE <CTRL-C> TO TERMINATE\n"); printf("TYPE <CTRL-C> TO TERMINATE\n");
itti_wait_tasks_end(); itti_wait_tasks_end(NULL);
printf("Returned from ITTI signal handler\n"); printf("Returned from ITTI signal handler\n");
oai_exit=1; oai_exit=1;
printf("oai_exit=%d\n",oai_exit); printf("oai_exit=%d\n",oai_exit);