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



commit 7058aa259b1f8f1b2a0bba10f3a6181533ae8dc7
Author: Ell <ell_se yahoo com>
Date:   Mon Oct 1 03:30:08 2018 -0400

    app: add gimp_data_factory_data_cancel()
    
    Add a new GimpData::data_cancel() virtual function, and a
    corresponding gimp_data_factory_data_cancel() function.  This
    function should cancel any ongoing async operations related to the
    factory (i.e., included in its async set), and wait for the
    operations to finish.  Provide a default implementation that simply
    cancels and waits on the factory's async set.
    
    Use this function to cancel any ongoing operations during factory
    destruction, and in gimp_data_factory_data_free().
    
    Override this function in GimpFontFactory, for which we can't
    really cancel font loading, and simply cancel and clear the
    factory's async set without waiting for loading to finish, making
    sure that nothing happens (and, in particular, that the factory
    isn't being accessed, since it might be already dead) when loading
    does finish.
    
    (cherry picked from commit 6bc0b3b8ad4215897a93cdd6bdc1e522f48ff05a)

 app/core/gimpdatafactory.c | 27 ++++++++++++++++++++++++---
 app/core/gimpdatafactory.h |  3 +++
 app/text/gimpfontfactory.c | 45 ++++++++++++++++++++-------------------------
 3 files changed, 47 insertions(+), 28 deletions(-)
---
diff --git a/app/core/gimpdatafactory.c b/app/core/gimpdatafactory.c
index 1fb1c7b30a..3b4a6db52f 100644
--- a/app/core/gimpdatafactory.c
+++ b/app/core/gimpdatafactory.c
@@ -90,6 +90,7 @@ static gint64     gimp_data_factory_get_memsize         (GimpObject          *ob
                                                          gint64              *gui_size);
 
 static void       gimp_data_factory_real_data_save      (GimpDataFactory     *factory);
+static void       gimp_data_factory_real_data_cancel    (GimpDataFactory     *factory);
 static GimpData * gimp_data_factory_real_data_duplicate (GimpDataFactory     *factory,
                                                          GimpData            *data);
 static gboolean   gimp_data_factory_real_data_delete    (GimpDataFactory     *factory,
@@ -126,6 +127,7 @@ gimp_data_factory_class_init (GimpDataFactoryClass *klass)
   klass->data_init               = NULL;
   klass->data_refresh            = NULL;
   klass->data_save               = gimp_data_factory_real_data_save;
+  klass->data_cancel             = gimp_data_factory_real_data_cancel;
   klass->data_duplicate          = gimp_data_factory_real_data_duplicate;
   klass->data_delete             = gimp_data_factory_real_data_delete;
 
@@ -280,12 +282,12 @@ gimp_data_factory_get_property (GObject    *object,
 static void
 gimp_data_factory_finalize (GObject *object)
 {
-  GimpDataFactoryPrivate *priv = GET_PRIVATE (object);
+  GimpDataFactory        *factory = GIMP_DATA_FACTORY (object);
+  GimpDataFactoryPrivate *priv    = GET_PRIVATE (object);
 
   if (priv->async_set)
     {
-      gimp_cancelable_cancel (GIMP_CANCELABLE (priv->async_set));
-      gimp_waitable_wait (GIMP_WAITABLE (priv->async_set));
+      gimp_data_factory_data_cancel (factory);
 
       g_clear_object (&priv->async_set);
     }
@@ -391,6 +393,15 @@ gimp_data_factory_real_data_save (GimpDataFactory *factory)
   g_list_free (dirty);
 }
 
+static void
+gimp_data_factory_real_data_cancel (GimpDataFactory *factory)
+{
+  GimpDataFactoryPrivate *priv = GET_PRIVATE (factory);
+
+  gimp_cancelable_cancel (GIMP_CANCELABLE (priv->async_set));
+  gimp_waitable_wait     (GIMP_WAITABLE   (priv->async_set));
+}
+
 static GimpData *
 gimp_data_factory_real_data_duplicate (GimpDataFactory *factory,
                                        GimpData        *data)
@@ -536,6 +547,8 @@ gimp_data_factory_data_free (GimpDataFactory *factory)
 {
   g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
 
+  gimp_data_factory_data_cancel (factory);
+
   if (! gimp_container_is_empty (factory->priv->container))
     {
       gimp_container_freeze (factory->priv->container);
@@ -577,6 +590,14 @@ gimp_data_factory_data_wait (GimpDataFactory *factory)
   return TRUE;
 }
 
+void
+gimp_data_factory_data_cancel (GimpDataFactory *factory)
+{
+  g_return_if_fail (GIMP_IS_DATA_FACTORY (factory));
+
+  GIMP_DATA_FACTORY_GET_CLASS (factory)->data_cancel (factory);
+}
+
 gboolean
 gimp_data_factory_has_data_new_func (GimpDataFactory *factory)
 {
diff --git a/app/core/gimpdatafactory.h b/app/core/gimpdatafactory.h
index ad8ff12e9f..47c57ae9f8 100644
--- a/app/core/gimpdatafactory.h
+++ b/app/core/gimpdatafactory.h
@@ -62,6 +62,8 @@ struct _GimpDataFactoryClass
                                      GimpContext     *context);
   void           (* data_save)      (GimpDataFactory *factory);
 
+  void           (* data_cancel)    (GimpDataFactory *factory);
+
   GimpData     * (* data_duplicate) (GimpDataFactory  *factory,
                                      GimpData         *data);
   gboolean       (* data_delete)    (GimpDataFactory  *factory,
@@ -84,6 +86,7 @@ void            gimp_data_factory_data_free         (GimpDataFactory  *factory);
 
 GimpAsyncSet  * gimp_data_factory_get_async_set     (GimpDataFactory  *factory);
 gboolean        gimp_data_factory_data_wait         (GimpDataFactory  *factory);
+void            gimp_data_factory_data_cancel       (GimpDataFactory  *factory);
 
 gboolean        gimp_data_factory_has_data_new_func (GimpDataFactory  *factory);
 GimpData      * gimp_data_factory_data_new          (GimpDataFactory  *factory,
diff --git a/app/text/gimpfontfactory.c b/app/text/gimpfontfactory.c
index 8bb96cc967..2cf5ab4558 100644
--- a/app/text/gimpfontfactory.c
+++ b/app/text/gimpfontfactory.c
@@ -66,13 +66,12 @@ 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,
                                                      GimpContext     *context);
 static void       gimp_font_factory_data_save       (GimpDataFactory *factory);
+static void       gimp_font_factory_data_cancel     (GimpDataFactory *factory);
 static GimpData * gimp_font_factory_data_duplicate  (GimpDataFactory *factory,
                                                      GimpData        *data);
 static gboolean   gimp_font_factory_data_delete     (GimpDataFactory *factory,
@@ -105,14 +104,12 @@ G_DEFINE_TYPE_WITH_PRIVATE (GimpFontFactory, gimp_font_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;
+  factory_class->data_cancel    = gimp_font_factory_data_cancel;
   factory_class->data_duplicate = gimp_font_factory_data_duplicate;
   factory_class->data_delete    = gimp_font_factory_data_delete;
 }
@@ -123,25 +120,6 @@ gimp_font_factory_init (GimpFontFactory *factory)
   factory->priv = gimp_font_factory_get_instance_private (factory);
 }
 
-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)
@@ -193,6 +171,21 @@ gimp_font_factory_data_save (GimpDataFactory *factory)
   FcInitReinitialize ();
 }
 
+static void
+gimp_font_factory_data_cancel (GimpDataFactory *factory)
+{
+  GimpAsyncSet *async_set = gimp_data_factory_get_async_set (factory);
+
+  /* we can't really cancel font loading, so we just clear the async set and
+   * return without waiting for loading to finish.  we also cancel the async
+   * set beforehand, as a way to signal to
+   * gimp_font_factory_load_async_callback() that loading was canceled and the
+   * factory might be dead, and that it should just do nothing.
+   */
+  gimp_cancelable_cancel (GIMP_CANCELABLE (async_set));
+  gimp_async_set_clear (async_set);
+}
+
 static GimpData *
 gimp_font_factory_data_duplicate (GimpDataFactory *factory,
                                   GimpData        *data)
@@ -252,7 +245,9 @@ gimp_font_factory_load_async_callback (GimpAsync       *async,
 {
   GimpContainer *container;
 
-  /* the operation was canceled during factory destruction. bail. */
+  /* the operation was canceled and the factory might be dead (see
+   * gimp_font_factory_data_cancel()).  bail.
+   */
   if (gimp_async_is_canceled (async))
     return;
 


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