The health check tests use the testpoints() in the application
registration thread to force a pthread_exit() or simulate a
catastrophic error within the thread.
The testpoints were moved before the signal that the thread's
initialization was completed by recent changes. This caused the thread
to fail to complete its initialization, causing a deadlock of the
session daemon on launch.
This commit reports initialization errors through the
launch_application_registration_thread() function to the "main" thread
and shuts down the session daemon. It also moves the testpoints after
the thread's initialization to respect the test's intent.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
struct lttng_pipe *quit_pipe;
struct ust_cmd_queue *ust_cmd_queue;
sem_t ready;
struct lttng_pipe *quit_pipe;
struct ust_cmd_queue *ust_cmd_queue;
sem_t ready;
-static
-void mark_thread_as_ready(struct thread_notifiers *notifiers)
+static void set_thread_status(struct thread_notifiers *notifiers, bool running)
- DBG("Marking application registration thread as ready");
+ DBG("Marking application registration thread's state as %s", running ? "running" : "error");
+ notifiers->running = running;
sem_post(¬ifiers->ready);
}
sem_post(¬ifiers->ready);
}
-static
-void wait_until_thread_is_ready(struct thread_notifiers *notifiers)
+static bool wait_thread_status(struct thread_notifiers *notifiers)
{
DBG("Waiting for application registration thread to be ready");
sem_wait(¬ifiers->ready);
{
DBG("Waiting for application registration thread to be ready");
sem_wait(¬ifiers->ready);
- DBG("Application registration thread is ready");
+ if (notifiers->running) {
+ DBG("Application registration thread is ready");
+ } else {
+ ERR("Initialization of application registration thread failed");
+ }
+
+ return notifiers->running;
+}
+
+static void thread_init_cleanup(void *data)
+{
+ struct thread_notifiers *notifiers = data;
+
+ set_thread_status(notifiers, false);
DBG("[thread] Manage application registration started");
DBG("[thread] Manage application registration started");
+ pthread_cleanup_push(thread_init_cleanup, NULL);
health_register(health_sessiond, HEALTH_SESSIOND_TYPE_APP_REG);
health_register(health_sessiond, HEALTH_SESSIOND_TYPE_APP_REG);
- if (testpoint(sessiond_thread_registration_apps)) {
- goto error_testpoint;
- }
-
apps_sock = create_application_socket();
if (apps_sock < 0) {
goto error_listen;
apps_sock = create_application_socket();
if (apps_sock < 0) {
goto error_listen;
- mark_thread_as_ready(notifiers);
+ set_thread_status(notifiers, true);
+ pthread_cleanup_pop(0);
+
+ if (testpoint(sessiond_thread_registration_apps)) {
+ goto error_create_poll;
+ }
/*
* Pass 2 as size here for the thread quit pipe and apps_sock. Nothing
/*
* Pass 2 as size here for the thread quit pipe and apps_sock. Nothing
lttng_poll_clean(&events);
error_listen:
error_create_poll:
lttng_poll_clean(&events);
error_listen:
error_create_poll:
DBG("UST Registration thread cleanup complete");
if (err) {
health_error();
DBG("UST Registration thread cleanup complete");
if (err) {
health_error();
if (!thread) {
goto error;
}
if (!thread) {
goto error;
}
- wait_until_thread_is_ready(notifiers);
+ if (!wait_thread_status(notifiers)) {
+ lttng_thread_put(thread);
+ thread = NULL;
+ }
return thread;
error:
cleanup_application_registration_thread(notifiers);
return thread;
error:
cleanup_application_registration_thread(notifiers);