* NR_LTTNG_SESSIOND_READY must match the number of calls to
* sessiond_notify_ready().
*/
-#define NR_LTTNG_SESSIOND_READY 5
+#define NR_LTTNG_SESSIOND_READY 6
int lttng_sessiond_ready = NR_LTTNG_SESSIOND_READY;
int sessiond_check_thread_quit_pipe(int fd, uint32_t events)
}
sessiond_notify_ready();
+
ret = sem_post(&load_info->message_thread_ready);
if (ret) {
PERROR("sem_post message_thread_ready");
goto error;
}
+ /*
+ * Wait until all support threads are initialized before accepting
+ * commands.
+ */
+ while (uatomic_read(<tng_sessiond_ready) != 0) {
+ fd_set read_fds;
+ struct timeval timeout;
+
+ FD_ZERO(&read_fds);
+ FD_SET(thread_quit_pipe[0], &read_fds);
+ memset(&timeout, 0, sizeof(timeout));
+ timeout.tv_usec = 1000;
+
+ /*
+ * If a support thread failed to launch, it may signal that
+ * we must exit and the sessiond would never be marked as
+ * "ready".
+ *
+ * The timeout is set to 1ms, which serves as a way to
+ * pace down this check.
+ */
+ ret = select(thread_quit_pipe[0] + 1, &read_fds, NULL, NULL,
+ &timeout);
+ if (ret > 0 || (ret < 0 && errno != EINTR)) {
+ goto exit;
+ }
+ }
+
/* This testpoint is after we signal readiness to the parent. */
if (testpoint(sessiond_thread_manage_clients)) {
goto error;
struct lttng_pipe *ust32_channel_monitor_pipe = NULL,
*ust64_channel_monitor_pipe = NULL,
*kernel_channel_monitor_pipe = NULL;
- bool notification_thread_running = false;
- bool rotation_thread_running = false;
- bool timer_thread_running = false;
+ bool notification_thread_launched = false;
+ bool rotation_thread_launched = false;
+ bool timer_thread_launched = false;
struct lttng_pipe *ust32_channel_rotate_pipe = NULL,
*ust64_channel_rotate_pipe = NULL,
*kernel_channel_rotate_pipe = NULL;
stop_threads();
goto exit_notification;
}
- notification_thread_running = true;
+ notification_thread_launched = true;
/* Create timer thread. */
ret = pthread_create(&timer_thread, default_pthread_attr(),
stop_threads();
goto exit_notification;
}
- timer_thread_running = true;
+ timer_thread_launched = true;
/* rotation_thread_data acquires the pipes' read side. */
rotation_thread_handle = rotation_thread_handle_create(
stop_threads();
goto exit_rotation;
}
- rotation_thread_running = true;
+ rotation_thread_launched = true;
/* Create thread to manage the client socket */
ret = pthread_create(&client_thread, default_pthread_attr(),
* of the active session and channels at the moment of the teardown.
*/
if (notification_thread_handle) {
- if (notification_thread_running) {
+ if (notification_thread_launched) {
notification_thread_command_quit(
notification_thread_handle);
ret = pthread_join(notification_thread, &status);
}
if (rotation_thread_handle) {
- if (rotation_thread_running) {
+ if (rotation_thread_launched) {
ret = pthread_join(rotation_thread, &status);
if (ret) {
errno = ret;
rotation_thread_handle_destroy(rotation_thread_handle);
}
- if (timer_thread_running) {
+ if (timer_thread_launched) {
kill(getpid(), LTTNG_SESSIOND_SIG_EXIT);
ret = pthread_join(timer_thread, &status);
if (ret) {