X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fagent-thread.c;h=575f6aee934a504ddb6248d4e87610d622d0959c;hp=b238656812c69390b2d7e16ee841d7830cd3ba03;hb=1f4962443f25c371e4b54e97f9eb867d67cbf88e;hpb=04fd2d2e705f7d9956f4cb8b18f6c43452913a16 diff --git a/src/bin/lttng-sessiond/agent-thread.c b/src/bin/lttng-sessiond/agent-thread.c index b23865681..575f6aee9 100644 --- a/src/bin/lttng-sessiond/agent-thread.c +++ b/src/bin/lttng-sessiond/agent-thread.c @@ -31,6 +31,12 @@ #include "lttng-sessiond.h" #include "session.h" #include "utils.h" +#include "thread.h" + +struct thread_notifiers { + struct lttng_pipe *quit_pipe; + sem_t ready; +}; static int agent_tracing_enabled = -1; @@ -59,6 +65,10 @@ static void update_agent_app(struct agent_app *app) session_lock_list(); cds_list_for_each_entry_safe(session, stmp, &list->head, list) { + if (!session_get(session)) { + continue; + } + session_lock(session); if (session->ust_session) { struct agent *agt; @@ -71,6 +81,7 @@ static void update_agent_app(struct agent_app *app) rcu_read_unlock(); } session_unlock(session); + session_put(session); } session_unlock_list(); } @@ -287,15 +298,33 @@ static int write_agent_port(uint16_t port) config.agent_port_file_path.value); } +static +void mark_thread_as_ready(struct thread_notifiers *notifiers) +{ + DBG("Marking agent management thread as ready"); + sem_post(¬ifiers->ready); +} + +static +void wait_until_thread_is_ready(struct thread_notifiers *notifiers) +{ + DBG("Waiting for agent management thread to be ready"); + sem_wait(¬ifiers->ready); + DBG("Agent management thread is ready"); +} + /* * This thread manage application notify communication. */ -void *agent_thread_manage_registration(void *data) +static void *thread_agent_management(void *data) { int i, ret, pollfd; uint32_t revents, nb_fd; struct lttng_poll_event events; struct lttcomm_sock *reg_sock; + struct thread_notifiers *notifiers = data; + const int quit_pipe_read_fd = lttng_pipe_get_readfd( + notifiers->quit_pipe); DBG("[agent-thread] Manage agent application registration."); @@ -305,13 +334,18 @@ void *agent_thread_manage_registration(void *data) /* Agent initialization call MUST be called before starting the thread. */ assert(agent_apps_ht_by_sock); - /* Create pollset with size 2, quit pipe and socket. */ - ret = sessiond_set_thread_pollset(&events, 2); + /* Create pollset with size 2, quit pipe and registration socket. */ + ret = lttng_poll_create(&events, 2, LTTNG_CLOEXEC); if (ret < 0) { - sessiond_notify_ready(); goto error_poll_create; } + ret = lttng_poll_add(&events, quit_pipe_read_fd, + LPOLLIN | LPOLLERR); + if (ret < 0) { + goto error_tcp_socket; + } + reg_sock = init_tcp_socket(); if (reg_sock) { uint16_t port; @@ -322,12 +356,12 @@ void *agent_thread_manage_registration(void *data) if (ret) { ERR("[agent-thread] Failed to create agent port file: agent tracing will be unavailable"); /* Don't prevent the launch of the sessiond on error. */ - sessiond_notify_ready(); + mark_thread_as_ready(notifiers); goto error; } } else { /* Don't prevent the launch of the sessiond on error. */ - sessiond_notify_ready(); + mark_thread_as_ready(notifiers); goto error_tcp_socket; } @@ -336,7 +370,7 @@ void *agent_thread_manage_registration(void *data) * may start to query whether or not agent tracing is enabled. */ uatomic_set(&agent_tracing_enabled, 1); - sessiond_notify_ready(); + mark_thread_as_ready(notifiers); /* Add TCP socket to poll set. */ ret = lttng_poll_add(&events, reg_sock->fd, @@ -370,14 +404,8 @@ restart: revents = LTTNG_POLL_GETEV(&events, i); pollfd = LTTNG_POLL_GETFD(&events, i); - if (!revents) { - /* No activity for this FD (poll implementation). */ - continue; - } - /* Thread quit pipe has been closed. Killing thread. */ - ret = sessiond_check_thread_quit_pipe(pollfd, revents); - if (ret) { + if (pollfd == quit_pipe_read_fd) { goto exit; } @@ -441,9 +469,57 @@ error_tcp_socket: lttng_poll_clean(&events); error_poll_create: uatomic_set(&agent_tracing_enabled, 0); - DBG("[agent-thread] is cleaning up and stopping."); - + DBG("[agent-thread] Cleaning up and stopping."); rcu_thread_offline(); rcu_unregister_thread(); return NULL; } + +static bool shutdown_agent_management_thread(void *data) +{ + struct thread_notifiers *notifiers = data; + const int write_fd = lttng_pipe_get_writefd(notifiers->quit_pipe); + + return notify_thread_pipe(write_fd) == 1; +} + +static void cleanup_agent_management_thread(void *data) +{ + struct thread_notifiers *notifiers = data; + + lttng_pipe_destroy(notifiers->quit_pipe); + sem_destroy(¬ifiers->ready); + free(notifiers); +} + +bool launch_agent_management_thread(void) +{ + struct thread_notifiers *notifiers; + struct lttng_thread *thread; + + notifiers = zmalloc(sizeof(*notifiers)); + if (!notifiers) { + goto error_alloc; + } + + sem_init(¬ifiers->ready, 0, 0); + notifiers->quit_pipe = lttng_pipe_open(FD_CLOEXEC); + if (!notifiers->quit_pipe) { + goto error; + } + thread = lttng_thread_create("Agent management", + thread_agent_management, + shutdown_agent_management_thread, + cleanup_agent_management_thread, + notifiers); + if (!thread) { + goto error; + } + wait_until_thread_is_ready(notifiers); + lttng_thread_put(thread); + return true; +error: + cleanup_agent_management_thread(notifiers); +error_alloc: + return false; +}