-void rotation_thread_enqueue_job(struct rotation_thread_timer_queue *queue,
- enum rotation_thread_job_type job_type,
- struct ltt_session *session)
-{
- int ret;
- const char dummy = '!';
- struct rotation_thread_job *job = NULL;
- const char *job_type_str = get_job_type_str(job_type);
-
- pthread_mutex_lock(&queue->lock);
- if (timer_job_exists(queue, job_type, session)) {
- /*
- * This timer job is already pending, we don't need to add
- * it.
- */
- goto end;
- }
-
- job = zmalloc<rotation_thread_job>();
- if (!job) {
- PERROR("Failed to allocate rotation thread job of type \"%s\" for session \"%s\"",
- job_type_str, session->name);
- goto end;
- }
- /* No reason for this to fail as the caller must hold a reference. */
- (void) session_get(session);
-
- job->session = session;
- job->type = job_type;
- cds_list_add_tail(&job->head, &queue->list);
-
- ret = lttng_write(lttng_pipe_get_writefd(queue->event_pipe), &dummy,
- sizeof(dummy));
- if (ret < 0) {
- /*
- * We do not want to block in the timer handler, the job has
- * been enqueued in the list, the wakeup pipe is probably full,
- * the job will be processed when the rotation_thread catches
- * up.
- */
- DIAGNOSTIC_PUSH
- DIAGNOSTIC_IGNORE_LOGICAL_OP
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- DIAGNOSTIC_POP
- /*
- * Not an error, but would be surprising and indicate
- * that the rotation thread can't keep up with the
- * current load.
- */
- DBG("Wake-up pipe of rotation thread job queue is full");
- goto end;
- }
- PERROR("Failed to wake-up the rotation thread after pushing a job of type \"%s\" for session \"%s\"",
- job_type_str, session->name);
- goto end;
- }
-
-end:
- pthread_mutex_unlock(&queue->lock);
-}
-
-static
-int init_poll_set(struct lttng_poll_event *poll_set,
- struct rotation_thread_handle *handle)
-{
- int ret;
-
- /*
- * Create pollset with size 3:
- * - rotation thread quit pipe,
- * - rotation thread timer queue pipe,
- * - notification channel sock,
- */
- ret = lttng_poll_create(poll_set, 5, LTTNG_CLOEXEC);
- if (ret < 0) {
- goto error;
- }
-
- ret = lttng_poll_add(poll_set,
- lttng_pipe_get_readfd(handle->quit_pipe),
- LPOLLIN | LPOLLERR);
- if (ret < 0) {
- ERR("Failed to add quit pipe read fd to poll set");
- goto error;
- }
-
- ret = lttng_poll_add(poll_set,
- lttng_pipe_get_readfd(handle->rotation_timer_queue->event_pipe),
- LPOLLIN | LPOLLERR);
- if (ret < 0) {
- ERR("Failed to add rotate_pending fd to poll set");
- goto error;
- }
-
- return ret;
-error:
- lttng_poll_clean(poll_set);
- return ret;
-}
-
-static
-void fini_thread_state(struct rotation_thread *state)
-{
- lttng_poll_clean(&state->events);
- if (rotate_notification_channel) {
- lttng_notification_channel_destroy(rotate_notification_channel);
- }
-}
-
-static
-int init_thread_state(struct rotation_thread_handle *handle,
- struct rotation_thread *state)
-{
- int ret;
-
- memset(state, 0, sizeof(*state));
- lttng_poll_init(&state->events);
-
- ret = init_poll_set(&state->events, handle);
- if (ret) {
- ERR("Failed to initialize rotation thread poll set");
- goto end;
- }
-
- rotate_notification_channel = lttng_notification_channel_create(
- lttng_session_daemon_notification_endpoint);
- if (!rotate_notification_channel) {
- ERR("Could not create notification channel");
- ret = -1;
- goto end;
- }
- ret = lttng_poll_add(&state->events, rotate_notification_channel->socket,
- LPOLLIN | LPOLLERR);
- if (ret < 0) {
- ERR("Failed to add notification fd to pollset");
- goto end;
- }
-
-end:
- return ret;
-}
-
-static
-void check_session_rotation_pending_on_consumers(struct ltt_session *session,
- bool *_rotation_completed)