Commit a6486909 authored by Robert Schmidt's avatar Robert Schmidt

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).
parent 4700dde2
...@@ -24,6 +24,7 @@ ...@@ -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" { ...@@ -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))
{
pthread_mutex_init(&signal_mutex, NULL); int rc = sem_init(&itti_sem_block, 0, 0);
pthread_mutex_lock(&signal_mutex); AssertFatal(rc == 0, "error in sem_init(): %d %s\n", errno, strerror(errno));
signal(SIGTERM, catch_sigterm); if (handler == NULL) /* no handler given: install default */
signal(SIGINT, catch_sigterm); 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) {} void itti_update_lte_time(uint32_t frame, uint8_t slot) {}
......
...@@ -550,10 +550,13 @@ MessageDef *itti_alloc_new_message_sized( ...@@ -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.
......
...@@ -614,7 +614,7 @@ int main ( int argc, char **argv ) ...@@ -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
......
...@@ -699,7 +699,7 @@ int main( int argc, char **argv ) { ...@@ -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);
......
...@@ -153,7 +153,7 @@ int main(int argc, char **argv) ...@@ -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");
......
...@@ -733,7 +733,7 @@ int main( int argc, char **argv ) { ...@@ -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);
......
...@@ -563,7 +563,7 @@ int main( int argc, char **argv ) { ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment