gtype: Add GTypeFinalizable

An interface to allow GTypeInstances to control the memory management of
their instance structure when they get freed by g_type_free_instance().
This commit is contained in:
Emmanuele Bassi 2024-07-22 16:52:52 +01:00
parent 3c53fb8790
commit 90ad82d9b0
2 changed files with 73 additions and 1 deletions

View File

@ -1999,7 +1999,24 @@ g_type_free_instance (GTypeInstance *instance)
NODE_NAME (node));
return;
}
if (G_IS_TYPE_FINALIZABLE (instance))
{
GTypeFinalizableInterface *iface = G_TYPE_FINALIZABLE_GET_IFACE (instance);
GType parent_type = g_type_parent (class->g_type);
if (iface->finalize != NULL)
iface->finalize ((GTypeFinalizable *) instance);
iface = g_type_interface_peek_parent (iface);
while (iface != NULL)
{
if (iface->finalize != NULL)
iface->finalize ((GTypeFinalizable *) instance);
iface = g_type_interface_peek_parent (iface);
}
}
instance->g_class = NULL;
private_size = node->data->instance.private_size;
ivar_size = node->data->instance.instance_size;
@ -4972,3 +4989,10 @@ g_type_init_internal (void)
_g_value_transforms_init ();
}
static void
g_type_finalizable_default_init (GTypeFinalizableInterface *iface)
{
}
G_DEFINE_INTERFACE (GTypeFinalizable, g_type_finalizable, G_TYPE_INVALID)

View File

@ -427,6 +427,8 @@ typedef struct _GInterfaceInfo GInterfaceInfo;
typedef struct _GTypeValueTable GTypeValueTable;
typedef struct _GTypeQuery GTypeQuery;
typedef struct _GTypeFinalizable GTypeFinalizable;
typedef struct _GTypeFinalizableInterface GTypeFinalizableInterface;
/* Basic Type Structures
*/
@ -480,6 +482,34 @@ struct _GTypeQuery
guint instance_size;
};
/**
* GTypeFinalizable:
*
* An interface for finalizable types.
*
* Instance types that allocate data on the instance structure and wish
* to free their resources when [func@GObject.type_free_instance] is called,
* should implement the [vfunc@GObject.TypeFinalizable.finalize] virtual
* function of this interface.
*/
/**
* GTypeFinalizableInterface:
*
* An interface for finalizable types.
*/
struct _GTypeFinalizableInterface
{
GTypeInterface parent_iface;
/**
* GTypeFinalizableInterface::finalize:
* @self: the instance to finalize
*
* Finalizes the instance data.
*/
void (* finalize) (GTypeFinalizable *self);
};
/* Casts, checks and accessors for structured types
* usage of these macros is reserved to type implementations only
@ -2718,4 +2748,22 @@ const gchar * g_type_name_from_class (GTypeClass *g_class);
*/
#define GTYPE_TO_POINTER(t) ((gpointer) (guintptr) (t)) GLIB_AVAILABLE_MACRO_IN_2_80
GLIB_AVAILABLE_IN_ALL
GType g_type_finalizable_get_type (void) G_GNUC_CONST;
G_GNUC_UNUSED static inline GTypeFinalizable *
G_TYPE_FINALIZABLE (gpointer ptr) {
return G_TYPE_CHECK_INSTANCE_CAST (ptr, g_type_finalizable_get_type (), GTypeFinalizable);
}
G_GNUC_UNUSED static inline gboolean
G_IS_TYPE_FINALIZABLE (gpointer ptr) {
return G_TYPE_CHECK_INSTANCE_TYPE (ptr, g_type_finalizable_get_type ());
}
G_GNUC_UNUSED static inline GTypeFinalizableInterface *
G_TYPE_FINALIZABLE_GET_IFACE (gpointer ptr) {
return G_TYPE_INSTANCE_GET_INTERFACE (ptr, g_type_finalizable_get_type (), GTypeFinalizableInterface);
}
G_END_DECLS