struct rotation_thread_job {
enum rotation_thread_job_type type;
- uint64_t session_id;
+ struct ltt_session *session;
/* List member in struct rotation_thread_timer_queue. */
struct cds_list_head head;
};
abort();
}
- LOG(log_level, "Rotation thread timer queue still contains job of type %s targeting session %" PRIu64 " on destruction",
- job_type_str, job->session_id);
+ LOG(log_level, "Rotation thread timer queue still contains job of type %s targeting session \"%s\" on destruction",
+ job_type_str, job->session->name);
}
void rotation_thread_timer_queue_destroy(
*/
static
bool timer_job_exists(const struct rotation_thread_timer_queue *queue,
- enum rotation_thread_job_type job_type, uint64_t session_id)
+ enum rotation_thread_job_type job_type,
+ struct ltt_session *session)
{
bool exists = false;
struct rotation_thread_job *job;
cds_list_for_each_entry(job, &queue->list, head) {
- if (job->session_id == session_id && job->type == job_type) {
+ if (job->session == session && job->type == job_type) {
exists = true;
goto end;
}
}
void rotation_thread_enqueue_job(struct rotation_thread_timer_queue *queue,
- enum rotation_thread_job_type job_type, uint64_t session_id)
+ enum rotation_thread_job_type job_type,
+ struct ltt_session *session)
{
int ret;
const char * const dummy = "!";
const char *job_type_str = get_job_type_str(job_type);
pthread_mutex_lock(&queue->lock);
- if (timer_job_exists(queue, session_id, job_type)) {
+ if (timer_job_exists(queue, job_type, session)) {
/*
* This timer job is already pending, we don't need to add
* it.
job = zmalloc(sizeof(struct rotation_thread_job));
if (!job) {
- PERROR("Failed to allocate rotation thread job of type \"%s\" for session id %" PRIu64,
- job_type_str, session_id);
+ 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;
- job->session_id = session_id;
cds_list_add_tail(&job->head, &queue->list);
ret = lttng_write(lttng_pipe_get_writefd(queue->event_pipe), dummy,
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 id %" PRIu64,
- job_type_str, session_id);
+ 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;
}
pthread_mutex_unlock(&queue->lock);
session_lock_list();
- session = session_find_by_id(job->session_id);
+ session = job->session;
if (!session) {
- DBG("[rotation-thread] Session %" PRIu64 " not found",
- job->session_id);
+ DBG("[rotation-thread] Session \"%s\" not found",
+ session->name);
/*
* This is a non-fatal error, and we cannot report it to
* the user (timer), so just print the error and
* a positive value if no timer was created (not an error).
*/
static
-int timer_start(timer_t *timer_id, uint64_t session_id,
+int timer_start(timer_t *timer_id, struct ltt_session *session,
unsigned int timer_interval_us, int signal, bool one_shot)
{
int ret = 0, delete_ret;
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = signal;
- sev.sigev_value.sival_ptr = UINT_TO_PTR(session_id);
+ sev.sigev_value.sival_ptr = session;
ret = timer_create(CLOCK_MONOTONIC, &sev, timer_id);
if (ret == -1) {
PERROR("timer_create");
{
int ret;
+ if (!session_get(session)) {
+ ret = -1;
+ goto end;
+ }
DBG("Enabling session rotation pending check timer on session %" PRIu64,
session->id);
/*
* no need to go through the whole signal teardown scheme everytime.
*/
ret = timer_start(&session->rotation_pending_check_timer,
- session->id, interval_us,
+ session, interval_us,
LTTNG_SESSIOND_SIG_PENDING_ROTATION_CHECK,
/* one-shot */ true);
if (ret == 0) {
session->rotation_pending_check_timer_enabled = true;
}
-
+end:
return ret;
}
ERR("Failed to stop rotate_pending_check timer");
} else {
session->rotation_pending_check_timer_enabled = false;
+ /*
+ * The timer's reference to the session can be released safely.
+ */
+ session_put(session);
}
return ret;
}
{
int ret;
+ if (!session_get(session)) {
+ ret = -1;
+ goto end;
+ }
DBG("Enabling scheduled rotation timer on session \"%s\" (%ui µs)", session->name,
interval_us);
- ret = timer_start(&session->rotation_schedule_timer, session->id,
+ ret = timer_start(&session->rotation_schedule_timer, session,
interval_us, LTTNG_SESSIOND_SIG_SCHEDULED_ROTATION,
/* one-shot */ false);
if (ret < 0) {
}
session->rotation_schedule_timer_enabled = false;
+ /* The timer's reference to the session can be released safely. */
+ session_put(session);
ret = 0;
end:
return ret;
} else if (signr == LTTNG_SESSIOND_SIG_EXIT) {
goto end;
} else if (signr == LTTNG_SESSIOND_SIG_PENDING_ROTATION_CHECK) {
+ struct ltt_session *session =
+ (struct ltt_session *) info.si_value.sival_ptr;
+
rotation_thread_enqueue_job(ctx->rotation_thread_job_queue,
ROTATION_THREAD_JOB_TYPE_CHECK_PENDING_ROTATION,
- /* session_id */ PTR_TO_UINT(info.si_value.sival_ptr));
+ session);
+ session_lock_list();
+ session_put(session);
+ session_unlock_list();
} else if (signr == LTTNG_SESSIOND_SIG_SCHEDULED_ROTATION) {
rotation_thread_enqueue_job(ctx->rotation_thread_job_queue,
ROTATION_THREAD_JOB_TYPE_SCHEDULED_ROTATION,
- /* session_id */ PTR_TO_UINT(info.si_value.sival_ptr));
+ (struct ltt_session *) info.si_value.sival_ptr);
+ /*
+ * The scheduled periodic rotation timer is not in
+ * "one-shot" mode. The reference to the session is not
+ * released since the timer is still enabled and can
+ * still fire.
+ */
} else {
ERR("Unexpected signal %d\n", info.si_signo);
}