Fix: flush the rotation thread's job queue on exit
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 28 Nov 2018 21:12:25 +0000 (16:12 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 5 Dec 2018 17:25:11 +0000 (12:25 -0500)
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 <jeremie.galarneau@efficios.com>
src/bin/lttng-sessiond/rotation-thread.c

index a0b924865d3e02fe04fc5ebd5c2517cb69ee165e..043993a60484130450dbe3dd75818b72ea9f4b66 100644 (file)
@@ -715,15 +715,6 @@ int handle_job_queue(struct rotation_thread_handle *handle,
                struct rotation_thread_timer_queue *queue)
 {
        int ret = 0;
                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;
 
        for (;;) {
                struct ltt_session *session;
@@ -977,23 +968,43 @@ void *thread_rotation(void *data)
                                goto error;
                        }
 
                                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;
                                }
                                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.028795 seconds and 4 git commands to generate.