#include "ht-cleanup.h"
#include "sessiond-config.h"
#include "timer.h"
+#include "thread.h"
static const char *help_msg =
#ifdef LTTNG_EMBED_HELP
static pthread_t kernel_thread;
static pthread_t dispatch_thread;
static pthread_t health_thread;
-static pthread_t ht_cleanup_thread;
static pthread_t agent_reg_thread;
static pthread_t load_session_thread;
static pthread_t notification_thread;
static void sessiond_cleanup(void)
{
int ret;
- struct ltt_session *sess, *stmp;
struct ltt_session_list *session_list = session_get_list();
DBG("Cleanup sessiond");
DBG("Removing directory %s", config.consumerd64_path.value);
(void) rmdir(config.consumerd64_path.value);
- DBG("Cleaning up all sessions");
-
- /* Destroy session list mutex */
- if (session_list) {
- session_lock_list();
- /* Cleanup ALL session */
- cds_list_for_each_entry_safe(sess, stmp,
- &session_list->head, list) {
- if (sess->destroyed) {
- continue;
- }
- cmd_destroy_session(sess,
- notification_thread_handle);
- }
- session_unlock_list();
- pthread_mutex_destroy(&session_list->lock);
- }
+ pthread_mutex_destroy(&session_list->lock);
wait_consumer(&kconsumer_data);
wait_consumer(&ustconsumer64_data);
health_code_update();
+ /* Set state as running. */
+ sessiond_set_client_thread_state(true);
+
while (1) {
const struct cmd_completion_handler *cmd_completion_handler;
errno = ret;
PERROR("join_consumer ust64");
}
+
+ /* Set state as non-running. */
+ sessiond_set_client_thread_state(false);
return NULL;
}
return ret;
}
+static void destroy_all_sessions_and_wait(void)
+{
+ struct ltt_session *session, *tmp;
+ struct ltt_session_list *session_list;
+
+ session_list = session_get_list();
+ DBG("Initiating destruction of all sessions");
+
+ if (!session_list) {
+ return;
+ }
+
+ /*
+ * Ensure that the client thread is no longer accepting new commands,
+ * which could cause new sessions to be created.
+ */
+ sessiond_wait_client_thread_stopped();
+
+ session_lock_list();
+ /* Initiate the destruction of all sessions. */
+ cds_list_for_each_entry_safe(session, tmp,
+ &session_list->head, list) {
+ if (!session_get(session)) {
+ continue;
+ }
+
+ session_lock(session);
+ if (session->destroyed) {
+ goto unlock_session;
+ }
+ (void) cmd_destroy_session(session,
+ notification_thread_handle);
+ unlock_session:
+ session_unlock(session);
+ session_put(session);
+ }
+ session_unlock_list();
+
+ /* Wait for the destruction of all sessions to complete. */
+ DBG("Waiting for the destruction of all sessions to complete");
+ session_list_wait_empty();
+ DBG("Destruction of all sessions completed");
+}
+
/*
* main
*/
bool notification_thread_launched = false;
bool rotation_thread_launched = false;
bool timer_thread_launched = false;
+ struct lttng_thread *ht_cleanup_thread = NULL;
struct timer_thread_parameters timer_thread_ctx;
/* Queue of rotation jobs populated by the sessiond-timer. */
struct rotation_thread_timer_queue *rotation_timer_queue = NULL;
}
/* Create thread to clean up RCU hash tables */
- if (init_ht_cleanup_thread(&ht_cleanup_thread)) {
+ ht_cleanup_thread = launch_ht_cleanup_thread();
+ if (!ht_cleanup_thread) {
retval = -1;
goto exit_ht_cleanup;
}
PERROR("pthread_join load_session_thread");
retval = -1;
}
+
+ /* Initiate teardown once activity occurs on the quit pipe. */
+ sessiond_wait_for_quit_pipe(-1U);
+ destroy_all_sessions_and_wait();
exit_load_session:
if (is_root && !config.no_kernel) {
PERROR("pthread_join health thread");
retval = -1;
}
+ lttng_thread_list_shutdown_orphans();
exit_health:
exit_init_data:
}
}
+ if (ht_cleanup_thread) {
+ lttng_thread_shutdown(ht_cleanup_thread);
+ lttng_thread_put(ht_cleanup_thread);
+ }
+
/*
* After the rotation and timer thread have quit, we can safely destroy
* the rotation_timer_queue.
rcu_thread_offline();
rcu_unregister_thread();
- ret = fini_ht_cleanup_thread(&ht_cleanup_thread);
- if (ret) {
- retval = -1;
- }
lttng_pipe_destroy(ust32_channel_monitor_pipe);
lttng_pipe_destroy(ust64_channel_monitor_pipe);
lttng_pipe_destroy(kernel_channel_monitor_pipe);