[glib] gtask: re-fix tasks-blocking-other-tasks



commit 4dae2d8289afabb59e3889118c392a09efea18a1
Author: Dan Winship <danw gnome org>
Date:   Sat Oct 24 10:37:22 2015 -0400

    gtask: re-fix tasks-blocking-other-tasks
    
    The new "slowly add more task threads" code doesn't fully deal with
    apps that queue lots and lots of tasks which then block on tasks from
    their task threads. Fix this by bringing back the "task is blocking
    other task" check and making sure that such tasks get bumped to the
    front of the queue.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=687223

 gio/gtask.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)
---
diff --git a/gio/gtask.c b/gio/gtask.c
index 1207846..2e99e12 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -559,6 +559,7 @@ struct _GTask {
   gboolean thread_cancelled;
   gboolean synchronous;
   gboolean thread_complete;
+  gboolean blocking_other_task;
 
   GError *error;
   union {
@@ -592,6 +593,7 @@ G_DEFINE_TYPE_WITH_CODE (GTask, g_task, G_TYPE_OBJECT,
 
 static GThreadPool *task_pool;
 static GMutex task_pool_mutex;
+static GPrivate task_private = G_PRIVATE_INIT (NULL);
 static GSource *task_pool_manager;
 static guint64 task_wait_time;
 static gint tasks_running;
@@ -1241,6 +1243,7 @@ task_pool_manager_timeout (gpointer user_data)
 static void
 g_task_thread_setup (void)
 {
+  g_private_set (&task_private, GUINT_TO_POINTER (TRUE));
   g_mutex_lock (&task_pool_mutex);
   tasks_running++;
 
@@ -1270,6 +1273,7 @@ g_task_thread_cleanup (void)
 
   tasks_running--;
   g_mutex_unlock (&task_pool_mutex);
+  g_private_set (&task_private, GUINT_TO_POINTER (FALSE));
 }
 
 static void
@@ -1359,6 +1363,8 @@ g_task_start_task_thread (GTask           *task,
                              task_thread_cancelled_disconnect_notify, 0);
     }
 
+  if (g_private_get (&task_private))
+    task->blocking_other_task = TRUE;
   g_thread_pool_push (task_pool, g_object_ref (task), NULL);
 }
 
@@ -1849,6 +1855,14 @@ g_task_compare_priority (gconstpointer a,
   const GTask *tb = b;
   gboolean a_cancelled, b_cancelled;
 
+  /* Tasks that are causing other tasks to block have higher
+   * priority.
+   */
+  if (ta->blocking_other_task && !tb->blocking_other_task)
+    return -1;
+  else if (tb->blocking_other_task && !ta->blocking_other_task)
+    return 1;
+
   /* Let already-cancelled tasks finish right away */
   a_cancelled = (ta->check_cancellable &&
                  g_cancellable_is_cancelled (ta->cancellable));


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