X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fclient.c;h=8cf28a9d6323b4859b9563a374422be5489a7484;hp=ea8ffd45fc066c3cfa16b4ac8017400361888e8d;hb=6cb45e931e18f489f1eb202396148529d86470a6;hpb=39d9954c97102b96fb444e52503c6bab02a9ee3f diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index ea8ffd45f..8cf28a9d6 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -40,31 +40,28 @@ static bool is_root; static struct thread_state { - pthread_cond_t cond; - pthread_mutex_t lock; - bool is_running; -} thread_state = { - .cond = PTHREAD_COND_INITIALIZER, - .lock = PTHREAD_MUTEX_INITIALIZER, - .is_running = false -}; - -void set_thread_state_running(void) + sem_t ready; + bool running; +} thread_state; + +static void set_thread_status(bool running) { - pthread_mutex_lock(&thread_state.lock); - thread_state.is_running = true; - pthread_cond_broadcast(&thread_state.cond); - pthread_mutex_unlock(&thread_state.lock); + DBG("Marking client thread's state as %s", running ? "running" : "error"); + thread_state.running = running; + sem_post(&thread_state.ready); } -static void wait_thread_state_running(void) +static bool wait_thread_status(void) { - pthread_mutex_lock(&thread_state.lock); - while (!thread_state.is_running) { - pthread_cond_wait(&thread_state.cond, - &thread_state.lock); + DBG("Waiting for client thread to be ready"); + sem_wait(&thread_state.ready); + if (thread_state.running) { + DBG("Client thread is ready"); + } else { + ERR("Initialization of client thread failed"); } - pthread_mutex_unlock(&thread_state.lock); + + return thread_state.running; } /* @@ -2071,6 +2068,11 @@ static void cleanup_client_thread(void *data) lttng_pipe_destroy(quit_pipe); } +static void thread_init_cleanup(void *data) +{ + set_thread_status(false); +} + /* * This thread manage all clients request using the unix client socket for * communication. @@ -2090,6 +2092,7 @@ static void *thread_manage_clients(void *data) is_root = (getuid() == 0); + pthread_cleanup_push(thread_init_cleanup, NULL); client_sock = create_client_sock(); if (client_sock < 0) { goto error_listen; @@ -2127,6 +2130,10 @@ static void *thread_manage_clients(void *data) goto error; } + /* Set state as running. */ + set_thread_status(true); + pthread_cleanup_pop(0); + /* This testpoint is after we signal readiness to the parent. */ if (testpoint(sessiond_thread_manage_clients)) { goto error; @@ -2138,9 +2145,6 @@ static void *thread_manage_clients(void *data) health_code_update(); - /* Set state as running. */ - set_thread_state_running(); - while (1) { const struct cmd_completion_handler *cmd_completion_handler; @@ -2362,9 +2366,11 @@ bool shutdown_client_thread(void *thread_data) struct lttng_thread *launch_client_thread(void) { + bool thread_running; struct lttng_pipe *client_quit_pipe; struct lttng_thread *thread; + sem_init(&thread_state.ready, 0, 0); client_quit_pipe = lttng_pipe_open(FD_CLOEXEC); if (!client_quit_pipe) { goto error; @@ -2383,8 +2389,11 @@ struct lttng_thread *launch_client_thread(void) * This thread is part of the threads that need to be fully * initialized before the session daemon is marked as "ready". */ - wait_thread_state_running(); - + thread_running = wait_thread_status(); + if (!thread_running) { + lttng_thread_put(thread); + thread = NULL; + } return thread; error: cleanup_client_thread(client_quit_pipe);