X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fclient.c;h=a889529a76967f881c9c05159ccdb55300336f51;hp=ea8ffd45fc066c3cfa16b4ac8017400361888e8d;hb=5d0a7bcb4407e434e2278ce3a7be2c30d00c3313;hpb=4ec029ed8d032ac98d8dc158a751841b7c150639 diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index ea8ffd45f..a889529a7 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; } /* @@ -478,7 +475,7 @@ static int create_kernel_session(struct ltt_session *session) ret = kernel_create_session(session, kernel_tracer_fd); if (ret < 0) { ret = LTTNG_ERR_KERN_SESS_FAIL; - goto error; + goto error_create; } /* Code flow safety */ @@ -500,6 +497,7 @@ static int create_kernel_session(struct ltt_session *session) error: trace_kernel_destroy_session(session->kernel_session); session->kernel_session = NULL; +error_create: return ret; } @@ -887,7 +885,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, if (need_tracing_session) { if (cmd_ctx->session->kernel_session == NULL) { ret = create_kernel_session(cmd_ctx->session); - if (ret < 0) { + if (ret != LTTNG_OK) { ret = LTTNG_ERR_KERN_SESS_FAIL; goto error; } @@ -2071,6 +2069,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 +2093,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 +2131,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 +2146,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 +2367,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 +2390,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);