[gimp/gimp-2-10] app: a few async font loading fixes



commit 50db2b66558ad5c5efcdb5d9707ff7109a38b3ab
Author: Ell <ell_se yahoo com>
Date:   Thu Jun 28 15:23:12 2018 -0400

    app: a few async font loading fixes
    
    In gimp_data_factory_finalize(), wait on the factory's async set
    after canceling it, and before continuing destruction.  It's not
    generally safe to just abandon an async op without waiting on it
    -- this is a font-specific hack, due to the fact we can't actually
    cancel font loading, and GimpFontFactory is prepared to handle
    this.
    
    Instead, in gimp_font_factory_finalize(), cancel and clear the
    async set, so that GimpDataFactory doesn't actually wait for
    loading to finish.
    
    In gimp_font_factory_load_async_callback(), don't try to acess the
    factory when the operation is canceled, since cancelation means the
    factory is already dead.  On the other hand, when the opeation
    isn't canceled, make sure to thaw the container even when font
    loading failed, so that we always match the freeze at the begining
    of the operation.
    
    (cherry picked from commit b5890e05b81974ce146bde7dd1a3e9b504a9c445)

 app/core/gimpdatafactory.c |  1 +
 app/text/gimpfontfactory.c | 39 +++++++++++++++++++++++++++++++--------
 2 files changed, 32 insertions(+), 8 deletions(-)
---
diff --git a/app/core/gimpdatafactory.c b/app/core/gimpdatafactory.c
index e969a57ee1..c7599699d6 100644
--- a/app/core/gimpdatafactory.c
+++ b/app/core/gimpdatafactory.c
@@ -288,6 +288,7 @@ gimp_data_factory_finalize (GObject *object)
   if (priv->async_set)
     {
       gimp_cancelable_cancel (GIMP_CANCELABLE (priv->async_set));
+      gimp_waitable_wait (GIMP_WAITABLE (priv->async_set));
 
       g_clear_object (&priv->async_set);
     }
diff --git a/app/text/gimpfontfactory.c b/app/text/gimpfontfactory.c
index 7fba37cfeb..79c684dcaa 100644
--- a/app/text/gimpfontfactory.c
+++ b/app/text/gimpfontfactory.c
@@ -37,6 +37,7 @@
 #include "core/gimp-parallel.h"
 #include "core/gimpasync.h"
 #include "core/gimpasyncset.h"
+#include "core/gimpcancelable.h"
 #include "core/gimpcontainer.h"
 
 #include "gimpfont.h"
@@ -65,6 +66,8 @@ struct _GimpFontFactoryPrivate
 #define GET_PRIVATE(obj) (((GimpFontFactory *) (obj))->priv)
 
 
+static void       gimp_font_factory_finalize        (GObject         *object);
+
 static void       gimp_font_factory_data_init       (GimpDataFactory *factory,
                                                      GimpContext     *context);
 static void       gimp_font_factory_data_refresh    (GimpDataFactory *factory,
@@ -101,8 +104,11 @@ G_DEFINE_TYPE (GimpFontFactory, gimp_font_factory, GIMP_TYPE_DATA_FACTORY)
 static void
 gimp_font_factory_class_init (GimpFontFactoryClass *klass)
 {
+  GObjectClass         *object_class  = G_OBJECT_CLASS (klass);
   GimpDataFactoryClass *factory_class = GIMP_DATA_FACTORY_CLASS (klass);
 
+  object_class->finalize        = gimp_font_factory_finalize;
+
   factory_class->data_init      = gimp_font_factory_data_init;
   factory_class->data_refresh   = gimp_font_factory_data_refresh;
   factory_class->data_save      = gimp_font_factory_data_save;
@@ -120,6 +126,25 @@ gimp_font_factory_init (GimpFontFactory *factory)
                                                GimpFontFactoryPrivate);
 }
 
+static void
+gimp_font_factory_finalize (GObject *object)
+{
+  GimpDataFactory *factory   = GIMP_DATA_FACTORY (object);
+  GimpAsyncSet    *async_set = gimp_data_factory_get_async_set (factory);
+
+  /* the finalize() method of GimpDataFactory normally cancels and waits on the
+   * async set, however, since we can't really cancel font loading, we just let
+   * the factory die without waiting for font loading to finish, by clearing
+   * the async set here.  we also cancel the async set beforehand, as a way to
+   * signal to gimp_font_factory_load_async_callback() that the factory is
+   * dead, and that it should just do nothing.
+   */
+  gimp_cancelable_cancel (GIMP_CANCELABLE (async_set));
+  gimp_async_set_clear (async_set);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
 static void
 gimp_font_factory_data_init (GimpDataFactory *factory,
                              GimpContext     *context)
@@ -230,13 +255,11 @@ gimp_font_factory_load_async_callback (GimpAsync       *async,
 {
   GimpContainer *container;
 
-  container = gimp_data_factory_get_container (GIMP_DATA_FACTORY (factory));
-
+  /* the operation was canceled during factory destruction. bail. */
   if (gimp_async_is_canceled (async))
-    {
-      gimp_container_thaw (container);
-      return;
-    }
+    return;
+
+  container = gimp_data_factory_get_container (GIMP_DATA_FACTORY (factory));
 
   if (gimp_async_is_finished (async))
     {
@@ -258,9 +281,9 @@ gimp_font_factory_load_async_callback (GimpAsync       *async,
 
       gimp_font_factory_load_names (container, PANGO_FONT_MAP (fontmap), context);
       g_object_unref (context);
-
-      gimp_container_thaw (container);
     }
+
+  gimp_container_thaw (container);
 }
 
 static void


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