X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Ftimer.c;h=9915767657fdbdc790d4b8568cd6ecb710b8a40d;hp=06d1d4a9803213850366699992729f7a26f0e3dd;hb=4a91420cefb94afc4a20042bdbe2564086dad3cb;hpb=8e319828707210e48a5f3e74495881594dba73e8 diff --git a/src/bin/lttng-sessiond/timer.c b/src/bin/lttng-sessiond/timer.c index 06d1d4a98..991576765 100644 --- a/src/bin/lttng-sessiond/timer.c +++ b/src/bin/lttng-sessiond/timer.c @@ -24,6 +24,7 @@ #include "timer.h" #include "health-sessiond.h" #include "rotation-thread.h" +#include "thread.h" #define LTTNG_SESSIOND_SIG_QS SIGRTMIN + 10 #define LTTNG_SESSIOND_SIG_EXIT SIGRTMIN + 11 @@ -149,7 +150,7 @@ void timer_signal_thread_qs(unsigned int signr) * 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; @@ -158,7 +159,7 @@ int timer_start(timer_t *timer_id, uint64_t session_id, 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"); @@ -214,6 +215,10 @@ int timer_session_rotation_pending_check_start(struct ltt_session *session, { int ret; + if (!session_get(session)) { + ret = -1; + goto end; + } DBG("Enabling session rotation pending check timer on session %" PRIu64, session->id); /* @@ -226,13 +231,13 @@ int timer_session_rotation_pending_check_start(struct ltt_session *session, * 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; } @@ -244,6 +249,7 @@ int timer_session_rotation_pending_check_stop(struct ltt_session *session) int ret; assert(session); + assert(session->rotation_pending_check_timer_enabled); DBG("Disabling session rotation pending check timer on session %" PRIu64, session->id); @@ -253,6 +259,10 @@ int timer_session_rotation_pending_check_stop(struct ltt_session *session) 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; } @@ -265,9 +275,13 @@ int timer_session_rotation_schedule_timer_start(struct ltt_session *session, { 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) { @@ -301,6 +315,8 @@ int timer_session_rotation_schedule_timer_stop(struct ltt_session *session) } 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; @@ -329,7 +345,8 @@ int timer_signal_init(void) /* * This thread is the sighandler for the timer signals. */ -void *timer_thread_func(void *data) +static +void *thread_timer(void *data) { int signr; sigset_t mask; @@ -370,13 +387,22 @@ void *timer_thread_func(void *data) } 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); } 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); } @@ -390,7 +416,27 @@ end: return NULL; } -void timer_exit(void) +static +bool shutdown_timer_thread(void *data) { - kill(getpid(), LTTNG_SESSIOND_SIG_EXIT); + return kill(getpid(), LTTNG_SESSIOND_SIG_EXIT) == 0; +} + +bool launch_timer_thread( + struct timer_thread_parameters *timer_thread_parameters) +{ + struct lttng_thread *thread; + + thread = lttng_thread_create("Timer", + thread_timer, + shutdown_timer_thread, + NULL, + timer_thread_parameters); + if (!thread) { + goto error; + } + lttng_thread_put(thread); + return true; +error: + return false; }