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:
@@ -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) {}
|
||||||
|
|||||||
@@ -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 )
|
|||||||
//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 ) {
|
|||||||
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)
|
|||||||
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 ) {
|
|||||||
// 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 ) {
|
|||||||
// 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);
|
||||||
|
|||||||
Reference in New Issue
Block a user