From: Jérémie Galarneau Date: Wed, 28 Nov 2018 21:12:25 +0000 (-0500) Subject: Fix: flush the rotation thread's job queue on exit X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=commitdiff_plain;h=85e17b276759c089bf2ba894c080963cad853afa Fix: flush the rotation thread's job queue on exit The rotation thread's job queue can transitively hold references to a number of ltt_session objects which will prevent the session daemon to exit as it waits for all sessions to have completed their destruction. This fix ensures that the job queue is flushed when activity is observed on the quit pipe. Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-sessiond/rotation-thread.c b/src/bin/lttng-sessiond/rotation-thread.c index a0b924865..043993a60 100644 --- a/src/bin/lttng-sessiond/rotation-thread.c +++ b/src/bin/lttng-sessiond/rotation-thread.c @@ -715,15 +715,6 @@ int handle_job_queue(struct rotation_thread_handle *handle, struct rotation_thread_timer_queue *queue) { int ret = 0; - int fd = lttng_pipe_get_readfd(queue->event_pipe); - char buf; - - ret = lttng_read(fd, &buf, 1); - if (ret != 1) { - ERR("[rotation-thread] Failed to read from wakeup pipe (fd = %i)", fd); - ret = -1; - goto end; - } for (;;) { struct ltt_session *session; @@ -977,23 +968,43 @@ void *thread_rotation(void *data) goto error; } - if (sessiond_check_thread_quit_pipe(fd, revents)) { - DBG("[rotation-thread] Quit pipe activity"); - /* TODO flush the queue. */ - goto exit; - } else if (fd == lttng_pipe_get_readfd(handle->rotation_timer_queue->event_pipe)) { + if (fd == rotate_notification_channel->socket) { + ret = handle_notification_channel(fd, handle, + &thread); + if (ret) { + ERR("[rotation-thread] Error occurred while handling activity on notification channel socket"); + goto error; + } + } else { + /* Job queue or quit pipe activity. */ + if (fd == lttng_pipe_get_readfd( + handle->rotation_timer_queue->event_pipe)) { + char buf; + + ret = lttng_read(fd, &buf, 1); + if (ret != 1) { + ERR("[rotation-thread] Failed to read from wakeup pipe (fd = %i)", fd); + ret = -1; + goto error; + } + } + + /* + * The job queue is serviced if there is + * activity on the quit pipe to ensure it is + * flushed and all references held in the queue + * are released. + */ ret = handle_job_queue(handle, &thread, handle->rotation_timer_queue); if (ret) { ERR("[rotation-thread] Failed to handle rotation timer pipe event"); goto error; } - } else if (fd == rotate_notification_channel->socket) { - ret = handle_notification_channel(fd, handle, - &thread); - if (ret) { - ERR("[rotation-thread] Error occurred while handling activity on notification channel socket"); - goto error; + + if (sessiond_check_thread_quit_pipe(fd, revents)) { + DBG("[rotation-thread] Quit pipe activity"); + goto exit; } } }