struct thread_notifiers {
struct lttng_pipe *quit_pipe;
struct ust_cmd_queue *ust_cmd_queue;
+ sem_t ready;
+ bool running;
};
/*
if (ret < 0) {
PERROR("Set file permissions failed on %s",
config.apps_unix_sock_path.value);
- goto end;
+ goto error_close_socket;
}
DBG3("Session daemon application socket created (fd = %d) ", apps_sock);
end:
umask(old_umask);
return ret;
+error_close_socket:
+ if (close(apps_sock)) {
+ PERROR("Failed to close application socket in error path");
+ }
+ apps_sock = -1;
+ ret = -1;
+ goto end;
}
/*
free(notifiers);
}
+static void set_thread_status(struct thread_notifiers *notifiers, bool running)
+{
+ DBG("Marking application registration thread's state as %s", running ? "running" : "error");
+ notifiers->running = running;
+ sem_post(¬ifiers->ready);
+}
+
+static bool wait_thread_status(struct thread_notifiers *notifiers)
+{
+ DBG("Waiting for application registration thread to be ready");
+ sem_wait(¬ifiers->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);
+}
+
/*
* This thread manage application registration.
*/
DBG("[thread] Manage application registration started");
+ pthread_cleanup_push(thread_init_cleanup, NULL);
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;
goto error_listen;
}
+ 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
* more will be added to this poll set.
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. */
if (pollfd == quit_pipe_read_fd) {
err = 0;
lttng_poll_clean(&events);
error_listen:
error_create_poll:
-error_testpoint:
DBG("UST Registration thread cleanup complete");
if (err) {
health_error();
return notify_thread_pipe(write_fd) == 1;
}
-bool launch_application_registration_thread(
+struct lttng_thread *launch_application_registration_thread(
struct ust_cmd_queue *cmd_queue)
{
struct lttng_pipe *quit_pipe;
struct thread_notifiers *notifiers = NULL;
struct lttng_thread *thread;
- quit_pipe = lttng_pipe_open(FD_CLOEXEC);
- if (!quit_pipe) {
- goto error;
- }
-
notifiers = zmalloc(sizeof(*notifiers));
if (!notifiers) {
+ goto error_alloc;
+ }
+ quit_pipe = lttng_pipe_open(FD_CLOEXEC);
+ if (!quit_pipe) {
goto error;
}
notifiers->quit_pipe = quit_pipe;
notifiers->ust_cmd_queue = cmd_queue;
+ sem_init(¬ifiers->ready, 0, 0);
thread = lttng_thread_create("UST application registration",
thread_application_registration,
if (!thread) {
goto error;
}
- lttng_thread_put(thread);
- return true;
+ if (!wait_thread_status(notifiers)) {
+ lttng_thread_put(thread);
+ thread = NULL;
+ }
+ return thread;
error:
cleanup_application_registration_thread(notifiers);
- return false;
+error_alloc:
+ return NULL;
}