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 @@
#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) {}
......
......@@ -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.
......
......@@ -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
......
......@@ -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);
......
......@@ -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");
......
......@@ -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);
......
......@@ -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);
......
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