Commit 6bc0b3b8 authored by Ell's avatar Ell

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.
parent 50bab438
......@@ -92,6 +92,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,
......@@ -128,6 +129,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;
......@@ -297,12 +299,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);
}
......@@ -409,6 +411,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)
......@@ -560,6 +571,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);
......@@ -601,6 +614,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)
{
......
......@@ -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,
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment