[gimp/gimp-2-10] app: add gimp_async_wait_until()



commit 89e9c8d9b3fc2d29d53108b638736fc83cb23609
Author: Ell <ell_se yahoo com>
Date:   Sat May 26 11:06:36 2018 -0400

    app: add gimp_async_wait_until()
    
    ... which is similar to gimp_async_wait(), taking an 'end_time'
    parameter, controlling how long to wait for the async operation to
    complete.
    
    (cherry picked from commit 68c57548fd930c7eb7aa3a63d0d16498b1c9b67c)

 app/core/gimpasync.c | 66 +++++++++++++++++++++++++++++++++++++++++-----------
 app/core/gimpasync.h |  2 ++
 2 files changed, 55 insertions(+), 13 deletions(-)
---
diff --git a/app/core/gimpasync.c b/app/core/gimpasync.c
index b4c5c787ef..b86dfb61bb 100644
--- a/app/core/gimpasync.c
+++ b/app/core/gimpasync.c
@@ -86,11 +86,12 @@ struct _GimpAsyncPrivate
 
 /*  local function prototypes  */
 
-static void       gimp_async_finalize (GObject   *object);
+static void       gimp_async_finalize      (GObject   *object);
 
-static gboolean   gimp_async_idle     (GimpAsync *async);
+static gboolean   gimp_async_idle          (GimpAsync *async);
 
-static void       gimp_async_stop     (GimpAsync *async);
+static void       gimp_async_stop          (GimpAsync *async);
+static void       gimp_async_run_callbacks (GimpAsync *async);
 
 
 G_DEFINE_TYPE (GimpAsync, gimp_async, G_TYPE_OBJECT)
@@ -187,6 +188,27 @@ gimp_async_stop (GimpAsync *async)
   g_cond_broadcast (&async->priv->cond);
 }
 
+static void
+gimp_async_run_callbacks (GimpAsync *async)
+{
+  if (async->priv->idle_id)
+    {
+      GimpAsyncCallbackInfo *callback_info;
+
+      g_source_remove (async->priv->idle_id);
+      async->priv->idle_id = 0;
+
+      while ((callback_info = g_queue_pop_head (&async->priv->callbacks)))
+        {
+          callback_info->callback (async, callback_info->data);
+
+          g_slice_free (GimpAsyncCallbackInfo, callback_info);
+        }
+
+      g_object_unref (async);
+    }
+}
+
 
 /*  public functions  */
 
@@ -228,22 +250,40 @@ gimp_async_wait (GimpAsync *async)
 
   g_mutex_unlock (&async->priv->mutex);
 
-  if (async->priv->idle_id)
-    {
-      GimpAsyncCallbackInfo *callback_info;
+  gimp_async_run_callbacks (async);
+}
 
-      g_source_remove (async->priv->idle_id);
-      async->priv->idle_id = 0;
+/* same as 'gimp_async_wait()', taking an additional 'end_time' parameter,
+ * specifying the maximal monotonic time until which to wait for 'async' for
+ * stop.
+ *
+ * returns TRUE if async has transitioned to the "stopped" state, or FALSE if
+ * the wait was interrupted before the transition.
+ */
+gboolean
+gimp_async_wait_until (GimpAsync *async,
+                       gint64     end_time)
+{
+  g_return_val_if_fail (GIMP_IS_ASYNC (async), FALSE);
 
-      while ((callback_info = g_queue_pop_head (&async->priv->callbacks)))
+  g_mutex_lock (&async->priv->mutex);
+
+  while (! async->priv->stopped)
+    {
+      if (! g_cond_wait_until (&async->priv->cond, &async->priv->mutex,
+                               end_time))
         {
-          callback_info->callback (async, callback_info->data);
+          g_mutex_unlock (&async->priv->mutex);
 
-          g_slice_free (GimpAsyncCallbackInfo, callback_info);
+          return FALSE;
         }
-
-      g_object_unref (async);
     }
+
+  g_mutex_unlock (&async->priv->mutex);
+
+  gimp_async_run_callbacks (async);
+
+  return TRUE;
 }
 
 /* registers a callback to be called when 'async' transitions to the "stopped"
diff --git a/app/core/gimpasync.h b/app/core/gimpasync.h
index 245aa70fb0..1cd7cb23c0 100644
--- a/app/core/gimpasync.h
+++ b/app/core/gimpasync.h
@@ -57,6 +57,8 @@ GimpAsync * gimp_async_new          (void);
 gboolean    gimp_async_is_stopped   (GimpAsync         *async);
 
 void        gimp_async_wait         (GimpAsync         *async);
+gboolean    gimp_async_wait_until   (GimpAsync         *async,
+                                     gint64             end_time);
 void        gimp_async_add_callback (GimpAsync         *async,
                                      GimpAsyncCallback  callback,
                                      gpointer           data);


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