#include "notification-thread-commands.h"
#include "lttng-sessiond.h"
#include "health-sessiond.h"
+#include "thread.h"
#include <urcu.h>
#include <urcu/list.h>
assert(cds_list_empty(&handle->cmd_queue.list));
pthread_mutex_destroy(&handle->cmd_queue.lock);
+ sem_destroy(&handle->ready);
if (handle->cmd_queue.event_pipe) {
lttng_pipe_destroy(handle->cmd_queue.event_pipe);
goto end;
}
- event_pipe = lttng_pipe_open(O_CLOEXEC);
+ sem_init(&handle->ready, 0, 0);
+
+ event_pipe = lttng_pipe_open(FD_CLOEXEC);
if (!event_pipe) {
ERR("event_pipe creation");
goto error;
if (getuid() == 0) {
ret = chown(sock_path, 0,
- utils_get_group_id(tracing_group_name));
+ utils_get_group_id(config.tracing_group_name.value));
if (ret) {
ERR("Failed to set the notification channel socket's group");
ret = -1;
assert(!ret);
}
if (state->channels_ht) {
- ret = cds_lfht_destroy(state->channels_ht,
- NULL);
+ ret = cds_lfht_destroy(state->channels_ht, NULL);
+ assert(!ret);
+ }
+ if (state->sessions_ht) {
+ ret = cds_lfht_destroy(state->sessions_ht, NULL);
+ assert(!ret);
+ }
+ /*
+ * Must be destroyed after all channels have been destroyed.
+ * See comment in struct lttng_session_trigger_list.
+ */
+ if (state->session_triggers_ht) {
+ ret = cds_lfht_destroy(state->session_triggers_ht, NULL);
assert(!ret);
}
-
if (state->notification_channel_socket >= 0) {
notification_channel_socket_destroy(
state->notification_channel_socket);
lttng_poll_clean(&state->events);
}
+static
+void mark_thread_as_ready(struct notification_thread_handle *handle)
+{
+ DBG("Marking notification thread as ready");
+ sem_post(&handle->ready);
+}
+
+static
+void wait_until_thread_is_ready(struct notification_thread_handle *handle)
+{
+ DBG("Waiting for notification thread to be ready");
+ sem_wait(&handle->ready);
+ DBG("Notification thread is ready");
+}
+
static
int init_thread_state(struct notification_thread_handle *handle,
struct notification_thread_state *state)
goto error;
}
+ state->session_triggers_ht = cds_lfht_new(DEFAULT_HT_SIZE, 1, 0,
+ CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
+ if (!state->session_triggers_ht) {
+ goto error;
+ }
+
state->channel_state_ht = cds_lfht_new(DEFAULT_HT_SIZE, 1, 0,
CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
if (!state->channel_state_ht) {
if (!state->channels_ht) {
goto error;
}
-
+ state->sessions_ht = cds_lfht_new(DEFAULT_HT_SIZE,
+ 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
+ if (!state->sessions_ht) {
+ goto error;
+ }
state->triggers_ht = cds_lfht_new(DEFAULT_HT_SIZE,
1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
if (!state->triggers_ht) {
goto error;
}
+ mark_thread_as_ready(handle);
end:
return 0;
error:
* This thread services notification channel clients and commands received
* from various lttng-sessiond components over a command queue.
*/
+static
void *thread_notification(void *data)
{
int ret;
goto end;
}
- /* Ready to handle client connections. */
- sessiond_notify_ready();
-
while (true) {
int fd_count, i;
end:
return NULL;
}
+
+static
+bool shutdown_notification_thread(void *thread_data)
+{
+ struct notification_thread_handle *handle = thread_data;
+
+ notification_thread_command_quit(handle);
+ return true;
+}
+
+struct lttng_thread *launch_notification_thread(
+ struct notification_thread_handle *handle)
+{
+ struct lttng_thread *thread;
+
+ thread = lttng_thread_create("Notification",
+ thread_notification,
+ shutdown_notification_thread,
+ NULL,
+ handle);
+ if (!thread) {
+ goto error;
+ }
+
+ /*
+ * Wait for the thread to be marked as "ready" before returning
+ * as other subsystems depend on the notification subsystem
+ * (e.g. rotation thread).
+ */
+ wait_until_thread_is_ready(handle);
+ return thread;
+error:
+ return NULL;
+}