[gegl] buffer: improve swap backend shutdown



commit 76c5f69bb15fb2f17c19d639b055a3c0de3818bf
Author: Ell <ell_se yahoo com>
Date:   Thu Aug 16 07:37:15 2018 -0400

    buffer: improve swap backend shutdown
    
    When shutting down the swap backend, cleanly exit the writer thread
    and free the queue/gap list even when the swap wasn't actually
    used, and no swap file was created.
    
    Additionally, when shutting down the writer thread, lock the queue
    mutex while setting the exit_thread flag and signalling the queue
    condition variable, to avoid a potential deadlock while joining the
    thread.

 gegl/buffer/gegl-tile-backend-swap.c | 57 +++++++++++++++++++++++-------------
 1 file changed, 36 insertions(+), 21 deletions(-)
---
diff --git a/gegl/buffer/gegl-tile-backend-swap.c b/gegl/buffer/gegl-tile-backend-swap.c
index aac6674a8..c3751b4b0 100644
--- a/gegl/buffer/gegl-tile-backend-swap.c
+++ b/gegl/buffer/gegl-tile-backend-swap.c
@@ -921,36 +921,51 @@ gegl_tile_backend_swap_class_init (GeglTileBackendSwapClass *klass)
 void
 gegl_tile_backend_swap_cleanup (void)
 {
-  if (in_fd != -1 && out_fd != -1)
-    {
-      exit_thread = TRUE;
-      g_cond_signal (&queue_cond);
-      g_thread_join (writer_thread);
+  if (! writer_thread)
+    return;
+
+  g_mutex_lock (&queue_mutex);
+  exit_thread = TRUE;
+  g_cond_signal (&queue_cond);
+  g_mutex_unlock (&queue_mutex);
+  g_thread_join (writer_thread);
+  writer_thread = NULL;
 
-      if (g_queue_get_length (queue) != 0)
-        g_warning ("tile-backend-swap writer queue wasn't empty before freeing\n");
+  if (g_queue_get_length (queue) != 0)
+    g_warning ("tile-backend-swap writer queue wasn't empty before freeing\n");
 
-      g_queue_free (queue);
+  g_queue_free (queue);
+  queue = NULL;
 
-      if (gap_list)
-        {
-          SwapGap *gap = gap_list->data;
+  if (gap_list)
+    {
+      SwapGap *gap = gap_list->data;
 
-          if (gap_list->next)
-            g_warning ("tile-backend-swap gap list had more than one element\n");
+      if (gap_list->next)
+        g_warning ("tile-backend-swap gap list had more than one element\n");
 
-          g_warn_if_fail (gap->start == 0 && gap->end == file_size);
+      g_warn_if_fail (gap->start == 0 && gap->end == file_size);
 
-          g_slice_free (SwapGap, gap_list->data);
-          g_list_free (gap_list);
-        }
-      else
-        g_warn_if_fail (file_size == 0);
+      g_slice_free (SwapGap, gap_list->data);
+      g_list_free (gap_list);
 
+      gap_list = NULL;
+    }
+  else
+    {
+      g_warn_if_fail (file_size == 0);
+    }
+
+  if (in_fd != -1)
+    {
       close (in_fd);
-      close (out_fd);
+      in_fd = -1;
+    }
 
-      in_fd = out_fd = -1;
+  if (out_fd != -1)
+    {
+      close (out_fd);
+      out_fd = -1;
     }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]