libgimp: make sure the GimpPlugIn and GimpPDB singletons get destroyed

Break reference cycles between the objects and the procedures they
keep by moving procedure destruction to dispose() and calling
g_object_run_dispose() before unrefing PLUG_IN and PDB in gimp.c.

Also some formatting and "Since: 3.0" annotation .
This commit is contained in:
Michael Natterer 2019-09-09 11:16:39 +02:00
parent 32c764dc60
commit b587740a10
4 changed files with 50 additions and 19 deletions

View file

@ -167,8 +167,12 @@ static GimpStackTraceMode stack_trace_mode = GIMP_STACK_TRACE_NEVER;
* #GimpPlugIn subclass type and the 'argc' and 'argv' that are passed
* to "main".
*
* See also: GIMP_MAIN().
*
* Returns: an exit status as defined by the C library,
* on success EXIT_SUCCESS.
*
* Since: 3.0
**/
gint
gimp_main (GType plug_in_type,
@ -597,7 +601,7 @@ gimp_main (GType plug_in_type,
* This function returns the plug-in's #GimpPlugIn instance, which can
* exist exactly once per running plug-in program.
*
* Returns: (transfer none) (nullable): The plug-in's #GimpPlugIn singleton, or %NULL.
* Returns: (transfer none) (nullable): The plug-in's #GimpPlugIn singleton.
*
* Since: 3.0
**/
@ -613,7 +617,7 @@ gimp_get_plug_in (void)
* This function returns the plug-in's #GimpPDB instance, which can
* exist exactly once per running plug-in program.
*
* Returns: (transfer none) (nullable): The plug-in's #GimpPDB singleton, or %NULL.
* Returns: (transfer none) (nullable): The plug-in's #GimpPDB singleton.
*
* Since: 3.0
**/
@ -918,7 +922,11 @@ gimp_close (void)
_gimp_plug_in_quit (PLUG_IN);
if (PDB)
g_object_run_dispose (G_OBJECT (PDB));
g_clear_object (&PDB);
g_object_run_dispose (G_OBJECT (PLUG_IN));
g_clear_object (&PLUG_IN);
}

View file

@ -89,6 +89,8 @@ G_BEGIN_DECLS
* GIMP_MAIN (MY_TYPE_PLUG_IN)
*
* at the toplevel of your file. No semicolon should be used.
*
* Since: 3.0
**/
#ifdef G_OS_WIN32

View file

@ -48,15 +48,16 @@
struct _GimpPDBPrivate
{
GimpPlugIn *plug_in;
GimpPlugIn *plug_in;
GHashTable *procedures;
GHashTable *procedures;
GimpPDBStatusType error_status;
gchar *error_message;
};
static void gimp_pdb_dispose (GObject *object);
static void gimp_pdb_finalize (GObject *object);
static void gimp_pdb_set_error (GimpPDB *pdb,
@ -73,6 +74,7 @@ gimp_pdb_class_init (GimpPDBClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gimp_pdb_dispose;
object_class->finalize = gimp_pdb_finalize;
}
@ -87,13 +89,22 @@ gimp_pdb_init (GimpPDB *pdb)
pdb->priv->error_status = GIMP_PDB_SUCCESS;
}
static void
gimp_pdb_dispose (GObject *object)
{
GimpPDB *pdb = GIMP_PDB (object);
g_clear_pointer (&pdb->priv->procedures, g_hash_table_unref);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gimp_pdb_finalize (GObject *object)
{
GimpPDB *pdb = GIMP_PDB (object);
g_clear_object (&pdb->priv->plug_in);
g_clear_pointer (&pdb->priv->procedures, g_hash_table_unref);
g_clear_pointer (&pdb->priv->error_message, g_free);
G_OBJECT_CLASS (parent_class)->finalize (object);

View file

@ -96,19 +96,20 @@ struct _GimpPlugInPrivate
};
static void gimp_plug_in_constructed (GObject *object);
static void gimp_plug_in_finalize (GObject *object);
static void gimp_plug_in_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_plug_in_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_plug_in_constructed (GObject *object);
static void gimp_plug_in_dispose (GObject *object);
static void gimp_plug_in_finalize (GObject *object);
static void gimp_plug_in_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_plug_in_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_plug_in_register (GimpPlugIn *plug_in,
GList *procedures);
static void gimp_plug_in_register (GimpPlugIn *plug_in,
GList *procedures);
static gboolean gimp_plug_in_write (GIOChannel *channel,
const guint8 *buf,
@ -158,6 +159,7 @@ gimp_plug_in_class_init (GimpPlugInClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gimp_plug_in_constructed;
object_class->dispose = gimp_plug_in_dispose;
object_class->finalize = gimp_plug_in_finalize;
object_class->set_property = gimp_plug_in_set_property;
object_class->get_property = gimp_plug_in_get_property;
@ -204,10 +206,9 @@ gimp_plug_in_constructed (GObject *object)
}
static void
gimp_plug_in_finalize (GObject *object)
gimp_plug_in_dispose (GObject *object)
{
GimpPlugIn *plug_in = GIMP_PLUG_IN (object);
GList *list;
if (plug_in->priv->extension_source_id)
{
@ -221,6 +222,15 @@ gimp_plug_in_finalize (GObject *object)
plug_in->priv->temp_procedures = NULL;
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gimp_plug_in_finalize (GObject *object)
{
GimpPlugIn *plug_in = GIMP_PLUG_IN (object);
GList *list;
g_clear_pointer (&plug_in->priv->translation_domain_name, g_free);
g_clear_object (&plug_in->priv->translation_domain_path);