Fix: flush the rotation thread's job queue on exit
[lttng-tools.git] / src / bin / lttng-sessiond / rotation-thread.c
index e8bd478e8db032934690979c86469b8de444d9f4..043993a60484130450dbe3dd75818b72ea9f4b66 100644 (file)
@@ -527,6 +527,19 @@ int check_session_rotation_pending(struct ltt_session *session,
        DBG("[rotation-thread] Checking for pending rotation on session \"%s\", trace archive %" PRIu64,
                        session->name, session->current_archive_id - 1);
 
+       /*
+        * The rotation-pending check timer of a session is launched in
+        * one-shot mode. If the rotation is incomplete, the rotation
+        * thread will re-enable the pending-check timer.
+        *
+        * The timer thread can't stop the timer itself since it is involved
+        * in the check for the timer's quiescence.
+        */
+       ret = timer_session_rotation_pending_check_stop(session);
+       if (ret) {
+               goto end;
+       }
+
        if (session->rotation_pending_local) {
                /* Updates session->rotation_pending_local as needed. */
                ret = check_session_rotation_pending_local(session);
@@ -702,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;
@@ -751,6 +755,7 @@ int handle_job_queue(struct rotation_thread_handle *handle,
                session_lock(session);
                ret = run_job(job, session, handle->notification_thread_handle);
                session_unlock(session);
+               /* Release reference held by the job. */
                session_put(session);
                session_unlock_list();
                free(job);
@@ -963,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;
                                }
                        }
                }
This page took 0.028793 seconds and 4 git commands to generate.