mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-20 22:29:17 +02:00
Merge branch 'ebassi/gtype-refcount' into 'main'
Drop TypeNode reference counting See merge request GNOME/glib!3255
This commit is contained in:
commit
cac9100960
540
gobject/gtype.c
540
gobject/gtype.c
@ -153,10 +153,6 @@ static void type_data_make_W (TypeNode *node,
|
|||||||
const GTypeInfo *info,
|
const GTypeInfo *info,
|
||||||
const GTypeValueTable *value_table);
|
const GTypeValueTable *value_table);
|
||||||
static inline void type_data_ref_Wm (TypeNode *node);
|
static inline void type_data_ref_Wm (TypeNode *node);
|
||||||
static inline void type_data_unref_U (TypeNode *node,
|
|
||||||
gboolean uncached);
|
|
||||||
static void type_data_last_unref_Wm (TypeNode * node,
|
|
||||||
gboolean uncached);
|
|
||||||
static inline gpointer type_get_qdata_L (TypeNode *node,
|
static inline gpointer type_get_qdata_L (TypeNode *node,
|
||||||
GQuark quark);
|
GQuark quark);
|
||||||
static inline void type_set_qdata_W (TypeNode *node,
|
static inline void type_set_qdata_W (TypeNode *node,
|
||||||
@ -192,7 +188,6 @@ typedef enum
|
|||||||
/* --- structures --- */
|
/* --- structures --- */
|
||||||
struct _TypeNode
|
struct _TypeNode
|
||||||
{
|
{
|
||||||
guint ref_count; /* (atomic) */
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
guint instance_count; /* (atomic) */
|
guint instance_count; /* (atomic) */
|
||||||
#endif
|
#endif
|
||||||
@ -228,7 +223,6 @@ struct _TypeNode
|
|||||||
#define NODE_PARENT_TYPE(node) (node->supers[1])
|
#define NODE_PARENT_TYPE(node) (node->supers[1])
|
||||||
#define NODE_FUNDAMENTAL_TYPE(node) (node->supers[node->n_supers])
|
#define NODE_FUNDAMENTAL_TYPE(node) (node->supers[node->n_supers])
|
||||||
#define NODE_NAME(node) (g_quark_to_string (node->qname))
|
#define NODE_NAME(node) (g_quark_to_string (node->qname))
|
||||||
#define NODE_REFCOUNT(node) ((guint) g_atomic_int_get ((int *) &(node)->ref_count))
|
|
||||||
#define NODE_IS_BOXED(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_BOXED)
|
#define NODE_IS_BOXED(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_BOXED)
|
||||||
#define NODE_IS_IFACE(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_INTERFACE)
|
#define NODE_IS_IFACE(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_INTERFACE)
|
||||||
#define CLASSED_NODE_IFACES_ENTRIES(node) (&(node)->_prot.iface_entries)
|
#define CLASSED_NODE_IFACES_ENTRIES(node) (&(node)->_prot.iface_entries)
|
||||||
@ -297,7 +291,7 @@ struct _ClassData
|
|||||||
CommonData common;
|
CommonData common;
|
||||||
guint16 class_size;
|
guint16 class_size;
|
||||||
guint16 class_private_size;
|
guint16 class_private_size;
|
||||||
int init_state; /* (atomic) - g_type_class_ref reads it unlocked */
|
int init_state; /* (atomic) - g_type_class_get reads it unlocked */
|
||||||
GBaseInitFunc class_init_base;
|
GBaseInitFunc class_init_base;
|
||||||
GBaseFinalizeFunc class_finalize_base;
|
GBaseFinalizeFunc class_finalize_base;
|
||||||
GClassInitFunc class_init;
|
GClassInitFunc class_init;
|
||||||
@ -311,7 +305,7 @@ struct _InstanceData
|
|||||||
CommonData common;
|
CommonData common;
|
||||||
guint16 class_size;
|
guint16 class_size;
|
||||||
guint16 class_private_size;
|
guint16 class_private_size;
|
||||||
int init_state; /* (atomic) - g_type_class_ref reads it unlocked */
|
int init_state; /* (atomic) - g_type_class_get reads it unlocked */
|
||||||
GBaseInitFunc class_init_base;
|
GBaseInitFunc class_init_base;
|
||||||
GBaseFinalizeFunc class_finalize_base;
|
GBaseFinalizeFunc class_finalize_base;
|
||||||
GClassInitFunc class_init;
|
GClassInitFunc class_init;
|
||||||
@ -1204,7 +1198,7 @@ type_data_make_W (TypeNode *node,
|
|||||||
!((G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_ABSTRACT) &
|
!((G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_ABSTRACT) &
|
||||||
GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))));
|
GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags))));
|
||||||
|
|
||||||
g_atomic_int_set ((int *) &node->ref_count, 1);
|
g_assert (node->data->common.value_table != NULL); /* paranoid */
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -1240,27 +1234,6 @@ type_data_ref_Wm (TypeNode *node)
|
|||||||
check_value_table_I (NODE_NAME (node),
|
check_value_table_I (NODE_NAME (node),
|
||||||
&tmp_value_table) ? &tmp_value_table : NULL);
|
&tmp_value_table) ? &tmp_value_table : NULL);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
g_assert (NODE_REFCOUNT (node) > 0);
|
|
||||||
|
|
||||||
g_atomic_int_inc ((int *) &node->ref_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gboolean
|
|
||||||
type_data_ref_U (TypeNode *node)
|
|
||||||
{
|
|
||||||
guint current;
|
|
||||||
|
|
||||||
do {
|
|
||||||
current = NODE_REFCOUNT (node);
|
|
||||||
|
|
||||||
if (current < 1)
|
|
||||||
return FALSE;
|
|
||||||
} while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current + 1));
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -1776,29 +1749,6 @@ type_iface_retrieve_holder_info_Wm (TypeNode *iface,
|
|||||||
return iholder; /* we don't modify write lock upon returning NULL */
|
return iholder; /* we don't modify write lock upon returning NULL */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
type_iface_blow_holder_info_Wm (TypeNode *iface,
|
|
||||||
GType instance_type)
|
|
||||||
{
|
|
||||||
IFaceHolder *iholder = iface_node_get_holders_L (iface);
|
|
||||||
|
|
||||||
g_assert (NODE_IS_IFACE (iface));
|
|
||||||
|
|
||||||
while (iholder->instance_type != instance_type)
|
|
||||||
iholder = iholder->next;
|
|
||||||
|
|
||||||
if (iholder->info && iholder->plugin)
|
|
||||||
{
|
|
||||||
g_free (iholder->info);
|
|
||||||
iholder->info = NULL;
|
|
||||||
|
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
|
||||||
g_type_plugin_unuse (iholder->plugin);
|
|
||||||
type_data_unref_U (iface, FALSE);
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maybe_issue_deprecation_warning (GType type)
|
maybe_issue_deprecation_warning (GType type)
|
||||||
{
|
{
|
||||||
@ -1892,7 +1842,7 @@ g_type_create_instance (GType type)
|
|||||||
maybe_issue_deprecation_warning (type);
|
maybe_issue_deprecation_warning (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
class = g_type_class_ref (type);
|
class = g_type_class_get (type);
|
||||||
|
|
||||||
/* We allocate the 'private' areas before the normal instance data, in
|
/* We allocate the 'private' areas before the normal instance data, in
|
||||||
* reverse order. This allows the private area of a particular class
|
* reverse order. This allows the private area of a particular class
|
||||||
@ -2035,8 +1985,6 @@ g_type_free_instance (GTypeInstance *instance)
|
|||||||
g_atomic_int_add ((int *) &node->instance_count, -1);
|
g_atomic_int_add ((int *) &node->instance_count, -1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_type_class_unref (class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2159,41 +2107,6 @@ type_iface_vtable_iface_init_Wm (TypeNode *iface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
type_iface_vtable_finalize_Wm (TypeNode *iface,
|
|
||||||
TypeNode *node,
|
|
||||||
GTypeInterface *vtable)
|
|
||||||
{
|
|
||||||
IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
|
|
||||||
IFaceHolder *iholder;
|
|
||||||
|
|
||||||
/* type_iface_retrieve_holder_info_Wm() doesn't modify write lock for returning NULL */
|
|
||||||
iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), FALSE);
|
|
||||||
if (!iholder)
|
|
||||||
return FALSE; /* we don't modify write lock upon FALSE */
|
|
||||||
|
|
||||||
g_assert (entry && entry->vtable == vtable && iholder->info);
|
|
||||||
|
|
||||||
entry->vtable = NULL;
|
|
||||||
entry->init_state = UNINITIALIZED;
|
|
||||||
if (iholder->info->interface_finalize || iface->data->iface.vtable_finalize_base)
|
|
||||||
{
|
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
|
||||||
if (iholder->info->interface_finalize)
|
|
||||||
iholder->info->interface_finalize (vtable, iholder->info->interface_data);
|
|
||||||
if (iface->data->iface.vtable_finalize_base)
|
|
||||||
iface->data->iface.vtable_finalize_base (vtable);
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
|
||||||
}
|
|
||||||
vtable->g_type = 0;
|
|
||||||
vtable->g_instance_type = 0;
|
|
||||||
g_free (vtable);
|
|
||||||
|
|
||||||
type_iface_blow_holder_info_Wm (iface, NODE_TYPE (node));
|
|
||||||
|
|
||||||
return TRUE; /* write lock modified */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
type_class_init_Wm (TypeNode *node,
|
type_class_init_Wm (TypeNode *node,
|
||||||
GTypeClass *pclass)
|
GTypeClass *pclass)
|
||||||
@ -2354,193 +2267,6 @@ type_class_init_Wm (TypeNode *node,
|
|||||||
g_atomic_int_set (&node->data->class.init_state, INITIALIZED);
|
g_atomic_int_set (&node->data->class.init_state, INITIALIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
type_data_finalize_class_ifaces_Wm (TypeNode *node)
|
|
||||||
{
|
|
||||||
guint i;
|
|
||||||
IFaceEntries *entries;
|
|
||||||
|
|
||||||
g_assert (node->is_instantiatable && node->data && node->data->class.class && NODE_REFCOUNT (node) == 0);
|
|
||||||
|
|
||||||
reiterate:
|
|
||||||
entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
|
|
||||||
for (i = 0; entries != NULL && i < IFACE_ENTRIES_N_ENTRIES (entries); i++)
|
|
||||||
{
|
|
||||||
IFaceEntry *entry = &entries->entry[i];
|
|
||||||
if (entry->vtable)
|
|
||||||
{
|
|
||||||
if (type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable))
|
|
||||||
{
|
|
||||||
/* refetch entries, IFACES_ENTRIES might be modified */
|
|
||||||
goto reiterate;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE,
|
|
||||||
* iface vtable came from parent
|
|
||||||
*/
|
|
||||||
entry->vtable = NULL;
|
|
||||||
entry->init_state = UNINITIALIZED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
type_data_finalize_class_U (TypeNode *node,
|
|
||||||
ClassData *cdata)
|
|
||||||
{
|
|
||||||
GTypeClass *class = cdata->class;
|
|
||||||
TypeNode *bnode;
|
|
||||||
|
|
||||||
g_assert (cdata->class && NODE_REFCOUNT (node) == 0);
|
|
||||||
|
|
||||||
if (cdata->class_finalize)
|
|
||||||
cdata->class_finalize (class, (gpointer) cdata->class_data);
|
|
||||||
|
|
||||||
/* call all base class destruction functions in descending order
|
|
||||||
*/
|
|
||||||
if (cdata->class_finalize_base)
|
|
||||||
cdata->class_finalize_base (class);
|
|
||||||
for (bnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode)))
|
|
||||||
if (bnode->data->class.class_finalize_base)
|
|
||||||
bnode->data->class.class_finalize_base (class);
|
|
||||||
|
|
||||||
g_free (cdata->class);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
type_data_last_unref_Wm (TypeNode *node,
|
|
||||||
gboolean uncached)
|
|
||||||
{
|
|
||||||
g_return_if_fail (node != NULL && node->plugin != NULL);
|
|
||||||
|
|
||||||
if (!node->data || NODE_REFCOUNT (node) == 0)
|
|
||||||
{
|
|
||||||
g_critical ("cannot drop last reference to unreferenced type '%s'",
|
|
||||||
NODE_NAME (node));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* call class cache hooks */
|
|
||||||
if (node->is_classed && node->data && node->data->class.class && static_n_class_cache_funcs && !uncached)
|
|
||||||
{
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
|
||||||
G_READ_LOCK (&type_rw_lock);
|
|
||||||
for (i = 0; i < static_n_class_cache_funcs; i++)
|
|
||||||
{
|
|
||||||
GTypeClassCacheFunc cache_func = static_class_cache_funcs[i].cache_func;
|
|
||||||
gpointer cache_data = static_class_cache_funcs[i].cache_data;
|
|
||||||
gboolean need_break;
|
|
||||||
|
|
||||||
G_READ_UNLOCK (&type_rw_lock);
|
|
||||||
need_break = cache_func (cache_data, node->data->class.class);
|
|
||||||
G_READ_LOCK (&type_rw_lock);
|
|
||||||
if (!node->data || NODE_REFCOUNT (node) == 0)
|
|
||||||
INVALID_RECURSION ("GType class cache function ", cache_func, NODE_NAME (node));
|
|
||||||
if (need_break)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
G_READ_UNLOCK (&type_rw_lock);
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* may have been re-referenced meanwhile */
|
|
||||||
if (g_atomic_int_dec_and_test ((int *) &node->ref_count))
|
|
||||||
{
|
|
||||||
GType ptype = NODE_PARENT_TYPE (node);
|
|
||||||
TypeData *tdata;
|
|
||||||
|
|
||||||
if (node->is_instantiatable)
|
|
||||||
{
|
|
||||||
/* destroy node->data->instance.mem_chunk */
|
|
||||||
}
|
|
||||||
|
|
||||||
tdata = node->data;
|
|
||||||
if (node->is_classed && tdata->class.class)
|
|
||||||
{
|
|
||||||
if (CLASSED_NODE_IFACES_ENTRIES_LOCKED (node) != NULL)
|
|
||||||
type_data_finalize_class_ifaces_Wm (node);
|
|
||||||
node->mutatable_check_cache = FALSE;
|
|
||||||
node->data = NULL;
|
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
|
||||||
type_data_finalize_class_U (node, &tdata->class);
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
|
||||||
}
|
|
||||||
else if (NODE_IS_IFACE (node) && tdata->iface.dflt_vtable)
|
|
||||||
{
|
|
||||||
node->mutatable_check_cache = FALSE;
|
|
||||||
node->data = NULL;
|
|
||||||
if (tdata->iface.dflt_finalize || tdata->iface.vtable_finalize_base)
|
|
||||||
{
|
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
|
||||||
if (tdata->iface.dflt_finalize)
|
|
||||||
tdata->iface.dflt_finalize (tdata->iface.dflt_vtable, (gpointer) tdata->iface.dflt_data);
|
|
||||||
if (tdata->iface.vtable_finalize_base)
|
|
||||||
tdata->iface.vtable_finalize_base (tdata->iface.dflt_vtable);
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
|
||||||
}
|
|
||||||
g_free (tdata->iface.dflt_vtable);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
node->mutatable_check_cache = FALSE;
|
|
||||||
node->data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* freeing tdata->common.value_table and its contents is taken care of
|
|
||||||
* by allocating it in one chunk with tdata
|
|
||||||
*/
|
|
||||||
g_free (tdata);
|
|
||||||
|
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
|
||||||
g_type_plugin_unuse (node->plugin);
|
|
||||||
if (ptype)
|
|
||||||
type_data_unref_U (lookup_type_node_I (ptype), FALSE);
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
type_data_unref_U (TypeNode *node,
|
|
||||||
gboolean uncached)
|
|
||||||
{
|
|
||||||
guint current;
|
|
||||||
|
|
||||||
do {
|
|
||||||
current = NODE_REFCOUNT (node);
|
|
||||||
|
|
||||||
if (current <= 1)
|
|
||||||
{
|
|
||||||
if (!node->plugin)
|
|
||||||
{
|
|
||||||
g_critical ("static type '%s' unreferenced too often",
|
|
||||||
NODE_NAME (node));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This is the last reference of a type from a plugin. We are
|
|
||||||
* experimentally disabling support for unloading type
|
|
||||||
* plugins, so don't allow the last ref to drop.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_assert (current > 0);
|
|
||||||
|
|
||||||
g_rec_mutex_lock (&class_init_rec_mutex); /* required locking order: 1) class_init_rec_mutex, 2) type_rw_lock */
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
|
||||||
type_data_last_unref_Wm (node, uncached);
|
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
|
||||||
g_rec_mutex_unlock (&class_init_rec_mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} while (!g_atomic_int_compare_and_exchange ((int *) &node->ref_count, current, current - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_type_add_class_cache_func: (skip)
|
* g_type_add_class_cache_func: (skip)
|
||||||
* @cache_data: data to be passed to @cache_func
|
* @cache_data: data to be passed to @cache_func
|
||||||
@ -2977,23 +2703,28 @@ g_type_add_interface_dynamic (GType instance_type,
|
|||||||
|
|
||||||
|
|
||||||
/* --- public API functions --- */
|
/* --- public API functions --- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_type_class_ref:
|
* g_type_class_get:
|
||||||
* @type: type ID of a classed type
|
* @type: type ID of a classed type
|
||||||
*
|
*
|
||||||
* Increments the reference count of the class structure belonging to
|
* Retrieves the type class of the given @type.
|
||||||
* @type. This function will demand-create the class if it doesn't
|
|
||||||
* exist already.
|
|
||||||
*
|
*
|
||||||
* Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
|
* This function will create the class on demand if it does not exist
|
||||||
* structure for the given type ID
|
* already.
|
||||||
|
*
|
||||||
|
* If you don't want to create the class, use g_type_class_peek() instead.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (type GObject.TypeClass): the class structure
|
||||||
|
* for the type
|
||||||
|
*
|
||||||
|
* Since: 2.84
|
||||||
*/
|
*/
|
||||||
gpointer
|
gpointer
|
||||||
g_type_class_ref (GType type)
|
g_type_class_get (GType type)
|
||||||
{
|
{
|
||||||
TypeNode *node;
|
TypeNode *node;
|
||||||
GType ptype;
|
GType ptype;
|
||||||
gboolean holds_ref;
|
|
||||||
GTypeClass *pclass;
|
GTypeClass *pclass;
|
||||||
|
|
||||||
/* optimize for common code path */
|
/* optimize for common code path */
|
||||||
@ -3005,14 +2736,11 @@ g_type_class_ref (GType type)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_LIKELY (type_data_ref_U (node)))
|
if (G_LIKELY (node->data != NULL))
|
||||||
{
|
{
|
||||||
if (G_LIKELY (g_atomic_int_get (&node->data->class.init_state) == INITIALIZED))
|
if (G_LIKELY (g_atomic_int_get (&node->data->class.init_state) == INITIALIZED))
|
||||||
return node->data->class.class;
|
return node->data->class.class;
|
||||||
holds_ref = TRUE;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
holds_ref = FALSE;
|
|
||||||
|
|
||||||
/* here, we either have node->data->class.class == NULL, or a recursive
|
/* here, we either have node->data->class.class == NULL, or a recursive
|
||||||
* call to g_type_class_ref() with a partly initialized class, or
|
* call to g_type_class_ref() with a partly initialized class, or
|
||||||
@ -3023,11 +2751,10 @@ g_type_class_ref (GType type)
|
|||||||
|
|
||||||
/* we need an initialized parent class for initializing derived classes */
|
/* we need an initialized parent class for initializing derived classes */
|
||||||
ptype = NODE_PARENT_TYPE (node);
|
ptype = NODE_PARENT_TYPE (node);
|
||||||
pclass = ptype ? g_type_class_ref (ptype) : NULL;
|
pclass = ptype ? g_type_class_get (ptype) : NULL;
|
||||||
|
|
||||||
G_WRITE_LOCK (&type_rw_lock);
|
G_WRITE_LOCK (&type_rw_lock);
|
||||||
|
|
||||||
if (!holds_ref)
|
|
||||||
type_data_ref_Wm (node);
|
type_data_ref_Wm (node);
|
||||||
|
|
||||||
if (!node->data->class.class) /* class uninitialized */
|
if (!node->data->class.class) /* class uninitialized */
|
||||||
@ -3035,37 +2762,47 @@ g_type_class_ref (GType type)
|
|||||||
|
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
G_WRITE_UNLOCK (&type_rw_lock);
|
||||||
|
|
||||||
if (pclass)
|
|
||||||
g_type_class_unref (pclass);
|
|
||||||
|
|
||||||
g_rec_mutex_unlock (&class_init_rec_mutex);
|
g_rec_mutex_unlock (&class_init_rec_mutex);
|
||||||
|
|
||||||
return node->data->class.class;
|
return node->data->class.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_type_class_ref:
|
||||||
|
* @type: type ID of a classed type
|
||||||
|
*
|
||||||
|
* Increments the reference count of the class structure belonging to
|
||||||
|
* @type.
|
||||||
|
*
|
||||||
|
* This function will demand-create the class if it doesn't exist already.
|
||||||
|
*
|
||||||
|
* Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
|
||||||
|
* structure for the given type ID
|
||||||
|
*
|
||||||
|
* Deprecated: 2.84: Use g_type_class_get() instead
|
||||||
|
*/
|
||||||
|
gpointer
|
||||||
|
g_type_class_ref (GType type)
|
||||||
|
{
|
||||||
|
return g_type_class_get (type);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_type_class_unref:
|
* g_type_class_unref:
|
||||||
* @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
|
* @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
|
||||||
*
|
*
|
||||||
* Decrements the reference count of the class structure being passed in.
|
* Decrements the reference count of the class structure being passed in.
|
||||||
|
*
|
||||||
* Once the last reference count of a class has been released, classes
|
* Once the last reference count of a class has been released, classes
|
||||||
* may be finalized by the type system, so further dereferencing of a
|
* may be finalized by the type system, so further dereferencing of a
|
||||||
* class pointer after g_type_class_unref() are invalid.
|
* class pointer after g_type_class_unref() are invalid.
|
||||||
|
*
|
||||||
|
* Deprecated: 2.84: Type class reference counting has been removed and type
|
||||||
|
* classes now cannot be finalized. This function no longer does anything.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
g_type_class_unref (gpointer g_class)
|
g_type_class_unref (gpointer g_class)
|
||||||
{
|
{
|
||||||
TypeNode *node;
|
|
||||||
GTypeClass *class = g_class;
|
|
||||||
|
|
||||||
g_return_if_fail (g_class != NULL);
|
|
||||||
|
|
||||||
node = lookup_type_node_I (class->g_type);
|
|
||||||
if (node && node->is_classed && NODE_REFCOUNT (node))
|
|
||||||
type_data_unref_U (node, FALSE);
|
|
||||||
else
|
|
||||||
g_critical ("cannot unreference class of invalid (unclassed) type '%s'",
|
|
||||||
type_descriptive_name_I (class->g_type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3073,55 +2810,53 @@ g_type_class_unref (gpointer g_class)
|
|||||||
* @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
|
* @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
|
||||||
*
|
*
|
||||||
* A variant of g_type_class_unref() for use in #GTypeClassCacheFunc
|
* A variant of g_type_class_unref() for use in #GTypeClassCacheFunc
|
||||||
* implementations. It unreferences a class without consulting the chain
|
* implementations.
|
||||||
|
*
|
||||||
|
* It unreferences a class without consulting the chain
|
||||||
* of #GTypeClassCacheFuncs, avoiding the recursion which would occur
|
* of #GTypeClassCacheFuncs, avoiding the recursion which would occur
|
||||||
* otherwise.
|
* otherwise.
|
||||||
|
*
|
||||||
|
* Deprecated: 2.84: Type class reference counting has been removed and type
|
||||||
|
* classes now cannot be finalized. This function no longer does anything.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
g_type_class_unref_uncached (gpointer g_class)
|
g_type_class_unref_uncached (gpointer g_class)
|
||||||
{
|
{
|
||||||
TypeNode *node;
|
|
||||||
GTypeClass *class = g_class;
|
|
||||||
|
|
||||||
g_return_if_fail (g_class != NULL);
|
|
||||||
|
|
||||||
node = lookup_type_node_I (class->g_type);
|
|
||||||
if (node && node->is_classed && NODE_REFCOUNT (node))
|
|
||||||
type_data_unref_U (node, TRUE);
|
|
||||||
else
|
|
||||||
g_critical ("cannot unreference class of invalid (unclassed) type '%s'",
|
|
||||||
type_descriptive_name_I (class->g_type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_type_class_peek:
|
* g_type_class_peek:
|
||||||
* @type: type ID of a classed type
|
* @type: type ID of a classed type
|
||||||
*
|
*
|
||||||
* This function is essentially the same as g_type_class_ref(),
|
* Retrieves the class for a give type.
|
||||||
* except that the classes reference count isn't incremented.
|
*
|
||||||
|
* This function is essentially the same as g_type_class_get(),
|
||||||
|
* except that the class may have not been instantiated yet.
|
||||||
|
*
|
||||||
* As a consequence, this function may return %NULL if the class
|
* As a consequence, this function may return %NULL if the class
|
||||||
* of the type passed in does not currently exist (hasn't been
|
* of the type passed in does not currently exist (hasn't been
|
||||||
* referenced before).
|
* referenced before).
|
||||||
*
|
*
|
||||||
* Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
|
* Returns: (type GObject.TypeClass) (transfer none) (nullable): the
|
||||||
* structure for the given type ID or %NULL if the class does not
|
* #GTypeClass structure for the given type ID or %NULL if the class
|
||||||
* currently exist
|
* does not currently exist
|
||||||
*/
|
*/
|
||||||
gpointer
|
gpointer
|
||||||
g_type_class_peek (GType type)
|
g_type_class_peek (GType type)
|
||||||
{
|
{
|
||||||
TypeNode *node;
|
TypeNode *node;
|
||||||
gpointer class;
|
|
||||||
|
|
||||||
node = lookup_type_node_I (type);
|
node = lookup_type_node_I (type);
|
||||||
if (node && node->is_classed && NODE_REFCOUNT (node) &&
|
if (node && node->is_classed)
|
||||||
g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
|
{
|
||||||
/* ref_count _may_ be 0 */
|
if (node->data == NULL)
|
||||||
class = node->data->class.class;
|
return NULL;
|
||||||
else
|
|
||||||
class = NULL;
|
|
||||||
|
|
||||||
return class;
|
if (G_LIKELY (g_atomic_int_get (&node->data->class.init_state) == INITIALIZED))
|
||||||
|
return node->data->class.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3131,9 +2866,9 @@ g_type_class_peek (GType type)
|
|||||||
* A more efficient version of g_type_class_peek() which works only for
|
* A more efficient version of g_type_class_peek() which works only for
|
||||||
* static types.
|
* static types.
|
||||||
*
|
*
|
||||||
* Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
|
* Returns: (type GObject.TypeClass) (transfer none) (nullable): the
|
||||||
* structure for the given type ID or %NULL if the class does not
|
* #GTypeClass structure for the given type ID or %NULL if the class
|
||||||
* currently exist or is dynamically loaded
|
* does not currently exist or is dynamically loaded
|
||||||
*
|
*
|
||||||
* Since: 2.4
|
* Since: 2.4
|
||||||
*/
|
*/
|
||||||
@ -3141,18 +2876,22 @@ gpointer
|
|||||||
g_type_class_peek_static (GType type)
|
g_type_class_peek_static (GType type)
|
||||||
{
|
{
|
||||||
TypeNode *node;
|
TypeNode *node;
|
||||||
gpointer class;
|
|
||||||
|
|
||||||
node = lookup_type_node_I (type);
|
node = lookup_type_node_I (type);
|
||||||
if (node && node->is_classed && NODE_REFCOUNT (node) &&
|
if (node && node->is_classed)
|
||||||
/* peek only static types: */ node->plugin == NULL &&
|
{
|
||||||
g_atomic_int_get (&node->data->class.init_state) == INITIALIZED)
|
if (node->data == NULL)
|
||||||
/* ref_count _may_ be 0 */
|
return NULL;
|
||||||
class = node->data->class.class;
|
|
||||||
else
|
|
||||||
class = NULL;
|
|
||||||
|
|
||||||
return class;
|
/* peek only static types */
|
||||||
|
if (node->plugin != NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (G_LIKELY (g_atomic_int_get (&node->data->class.init_state) == INITIALIZED))
|
||||||
|
return node->data->class.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3160,11 +2899,13 @@ g_type_class_peek_static (GType type)
|
|||||||
* @g_class: (type GObject.TypeClass): the #GTypeClass structure to
|
* @g_class: (type GObject.TypeClass): the #GTypeClass structure to
|
||||||
* retrieve the parent class for
|
* retrieve the parent class for
|
||||||
*
|
*
|
||||||
|
* Retrieves the class structure of the immediate parent type of the
|
||||||
|
* class passed in.
|
||||||
|
*
|
||||||
* This is a convenience function often needed in class initializers.
|
* This is a convenience function often needed in class initializers.
|
||||||
* It returns the class structure of the immediate parent type of the
|
*
|
||||||
* class passed in. Since derived classes hold a reference count on
|
* Since derived classes hold a reference on their parent classes as
|
||||||
* their parent classes as long as they are instantiated, the returned
|
* long as they are instantiated, the returned class will always exist.
|
||||||
* class will always exist.
|
|
||||||
*
|
*
|
||||||
* This function is essentially equivalent to:
|
* This function is essentially equivalent to:
|
||||||
* g_type_class_peek (g_type_parent (G_TYPE_FROM_CLASS (g_class)))
|
* g_type_class_peek (g_type_parent (G_TYPE_FROM_CLASS (g_class)))
|
||||||
@ -3207,7 +2948,7 @@ g_type_class_peek_parent (gpointer g_class)
|
|||||||
* Returns the #GTypeInterface structure of an interface to which the
|
* Returns the #GTypeInterface structure of an interface to which the
|
||||||
* passed in class conforms.
|
* passed in class conforms.
|
||||||
*
|
*
|
||||||
* Returns: (type GObject.TypeInterface) (transfer none): the #GTypeInterface
|
* Returns: (type GObject.TypeInterface) (transfer none) (nullable): the #GTypeInterface
|
||||||
* structure of @iface_type if implemented by @instance_class, %NULL
|
* structure of @iface_type if implemented by @instance_class, %NULL
|
||||||
* otherwise
|
* otherwise
|
||||||
*/
|
*/
|
||||||
@ -3237,11 +2978,12 @@ g_type_interface_peek (gpointer instance_class,
|
|||||||
* @g_iface: (type GObject.TypeInterface): a #GTypeInterface structure
|
* @g_iface: (type GObject.TypeInterface): a #GTypeInterface structure
|
||||||
*
|
*
|
||||||
* Returns the corresponding #GTypeInterface structure of the parent type
|
* Returns the corresponding #GTypeInterface structure of the parent type
|
||||||
* of the instance type to which @g_iface belongs. This is useful when
|
* of the instance type to which @g_iface belongs.
|
||||||
* deriving the implementation of an interface from the parent type and
|
|
||||||
* then possibly overriding some methods.
|
|
||||||
*
|
*
|
||||||
* Returns: (transfer none) (type GObject.TypeInterface): the
|
* This is useful when deriving the implementation of an interface from the
|
||||||
|
* parent type and then possibly overriding some methods.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (type GObject.TypeInterface) (nullable): the
|
||||||
* corresponding #GTypeInterface structure of the parent type of the
|
* corresponding #GTypeInterface structure of the parent type of the
|
||||||
* instance type to which @g_iface belongs, or %NULL if the parent
|
* instance type to which @g_iface belongs, or %NULL if the parent
|
||||||
* type doesn't conform to the interface
|
* type doesn't conform to the interface
|
||||||
@ -3285,12 +3027,43 @@ g_type_interface_peek_parent (gpointer g_iface)
|
|||||||
*
|
*
|
||||||
* Since: 2.4
|
* Since: 2.4
|
||||||
*
|
*
|
||||||
|
* Deprecated: 2.84: Use g_type_default_interface_get() instead
|
||||||
|
*
|
||||||
* Returns: (type GObject.TypeInterface) (transfer none): the default
|
* Returns: (type GObject.TypeInterface) (transfer none): the default
|
||||||
* vtable for the interface; call g_type_default_interface_unref()
|
* vtable for the interface; call g_type_default_interface_unref()
|
||||||
* when you are done using the interface.
|
* when you are done using the interface.
|
||||||
*/
|
*/
|
||||||
gpointer
|
gpointer
|
||||||
g_type_default_interface_ref (GType g_type)
|
g_type_default_interface_ref (GType g_type)
|
||||||
|
{
|
||||||
|
return g_type_default_interface_get (g_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_type_default_interface_get:
|
||||||
|
* @g_type: an interface type
|
||||||
|
*
|
||||||
|
* Returns the default interface vtable for the given @g_type.
|
||||||
|
*
|
||||||
|
* If the type is not currently in use, then the default vtable
|
||||||
|
* for the type will be created and initialized by calling
|
||||||
|
* the base interface init and default vtable init functions for
|
||||||
|
* the type (the @base_init and @class_init members of #GTypeInfo).
|
||||||
|
*
|
||||||
|
* If you don't want to create the interface vtable, you should use
|
||||||
|
* g_type_default_interface_peek() instead.
|
||||||
|
*
|
||||||
|
* Calling g_type_default_interface_get() is useful when you
|
||||||
|
* want to make sure that signals and properties for an interface
|
||||||
|
* have been installed.
|
||||||
|
*
|
||||||
|
* Returns: (type GObject.TypeInterface) (transfer none): the default
|
||||||
|
* vtable for the interface.
|
||||||
|
*
|
||||||
|
* Since: 2.84
|
||||||
|
*/
|
||||||
|
gpointer
|
||||||
|
g_type_default_interface_get (GType g_type)
|
||||||
{
|
{
|
||||||
TypeNode *node;
|
TypeNode *node;
|
||||||
gpointer dflt_vtable;
|
gpointer dflt_vtable;
|
||||||
@ -3298,8 +3071,7 @@ g_type_default_interface_ref (GType g_type)
|
|||||||
G_WRITE_LOCK (&type_rw_lock);
|
G_WRITE_LOCK (&type_rw_lock);
|
||||||
|
|
||||||
node = lookup_type_node_I (g_type);
|
node = lookup_type_node_I (g_type);
|
||||||
if (!node || !NODE_IS_IFACE (node) ||
|
if (!node || !NODE_IS_IFACE (node))
|
||||||
(node->data && NODE_REFCOUNT (node) == 0))
|
|
||||||
{
|
{
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
G_WRITE_UNLOCK (&type_rw_lock);
|
||||||
g_critical ("cannot retrieve default vtable for invalid or non-interface type '%s'",
|
g_critical ("cannot retrieve default vtable for invalid or non-interface type '%s'",
|
||||||
@ -3317,8 +3089,6 @@ g_type_default_interface_ref (GType g_type)
|
|||||||
type_iface_ensure_dflt_vtable_Wm (node);
|
type_iface_ensure_dflt_vtable_Wm (node);
|
||||||
g_rec_mutex_unlock (&class_init_rec_mutex);
|
g_rec_mutex_unlock (&class_init_rec_mutex);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
type_data_ref_Wm (node); /* ref_count >= 1 already */
|
|
||||||
|
|
||||||
dflt_vtable = node->data->iface.dflt_vtable;
|
dflt_vtable = node->data->iface.dflt_vtable;
|
||||||
G_WRITE_UNLOCK (&type_rw_lock);
|
G_WRITE_UNLOCK (&type_rw_lock);
|
||||||
@ -3346,7 +3116,7 @@ g_type_default_interface_peek (GType g_type)
|
|||||||
gpointer vtable;
|
gpointer vtable;
|
||||||
|
|
||||||
node = lookup_type_node_I (g_type);
|
node = lookup_type_node_I (g_type);
|
||||||
if (node && NODE_IS_IFACE (node) && NODE_REFCOUNT (node))
|
if (node && NODE_IS_IFACE (node) && node->data)
|
||||||
vtable = node->data->iface.dflt_vtable;
|
vtable = node->data->iface.dflt_vtable;
|
||||||
else
|
else
|
||||||
vtable = NULL;
|
vtable = NULL;
|
||||||
@ -3360,38 +3130,33 @@ g_type_default_interface_peek (GType g_type)
|
|||||||
* structure for an interface, as returned by g_type_default_interface_ref()
|
* structure for an interface, as returned by g_type_default_interface_ref()
|
||||||
*
|
*
|
||||||
* Decrements the reference count for the type corresponding to the
|
* Decrements the reference count for the type corresponding to the
|
||||||
* interface default vtable @g_iface. If the type is dynamic, then
|
* interface default vtable @g_iface.
|
||||||
* when no one is using the interface and all references have
|
*
|
||||||
* been released, the finalize function for the interface's default
|
* If the type is dynamic, then when no one is using the interface and all
|
||||||
* vtable (the @class_finalize member of #GTypeInfo) will be called.
|
* references have been released, the finalize function for the interface's
|
||||||
|
* default vtable (the @class_finalize member of #GTypeInfo) will be called.
|
||||||
*
|
*
|
||||||
* Since: 2.4
|
* Since: 2.4
|
||||||
|
*
|
||||||
|
* Deprecated: 2.84: Interface reference counting has been removed and
|
||||||
|
* interface types now cannot be finalized. This function no longer does
|
||||||
|
* anything.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
g_type_default_interface_unref (gpointer g_iface)
|
g_type_default_interface_unref (gpointer g_iface)
|
||||||
{
|
{
|
||||||
TypeNode *node;
|
|
||||||
GTypeInterface *vtable = g_iface;
|
|
||||||
|
|
||||||
g_return_if_fail (g_iface != NULL);
|
|
||||||
|
|
||||||
node = lookup_type_node_I (vtable->g_type);
|
|
||||||
if (node && NODE_IS_IFACE (node))
|
|
||||||
type_data_unref_U (node, FALSE);
|
|
||||||
else
|
|
||||||
g_critical ("cannot unreference invalid interface default vtable for '%s'",
|
|
||||||
type_descriptive_name_I (vtable->g_type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_type_name:
|
* g_type_name:
|
||||||
* @type: type to return name for
|
* @type: type to return name for
|
||||||
*
|
*
|
||||||
* Get the unique name that is assigned to a type ID. Note that this
|
* Get the unique name that is assigned to a type ID.
|
||||||
* function (like all other GType API) cannot cope with invalid type
|
*
|
||||||
* IDs. %G_TYPE_INVALID may be passed to this function, as may be any
|
* Note that this function (like all other GType API) cannot cope with
|
||||||
* other validly registered type ID, but randomized type IDs should
|
* invalid type IDs. %G_TYPE_INVALID may be passed to this function, as
|
||||||
* not be passed in and will most likely lead to a crash.
|
* may be any other validly registered type ID, but randomized type IDs
|
||||||
|
* should not be passed in and will most likely lead to a crash.
|
||||||
*
|
*
|
||||||
* Returns: (nullable): static type name or %NULL
|
* Returns: (nullable): static type name or %NULL
|
||||||
*/
|
*/
|
||||||
@ -4288,7 +4053,7 @@ type_check_is_value_type_U (GType type)
|
|||||||
restart_check:
|
restart_check:
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
if (node->data && NODE_REFCOUNT (node) > 0 &&
|
if (node->data &&
|
||||||
node->data->common.value_table->value_init)
|
node->data->common.value_table->value_init)
|
||||||
tflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags));
|
tflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags));
|
||||||
else if (NODE_IS_IFACE (node))
|
else if (NODE_IS_IFACE (node))
|
||||||
@ -4343,25 +4108,26 @@ g_type_check_value_holds (const GValue *value,
|
|||||||
* that implements or has internal knowledge of the implementation of
|
* that implements or has internal knowledge of the implementation of
|
||||||
* @type.
|
* @type.
|
||||||
*
|
*
|
||||||
* Returns: location of the #GTypeValueTable associated with @type or
|
* Returns: (nullable) (transfer none): location of the #GTypeValueTable
|
||||||
* %NULL if there is no #GTypeValueTable associated with @type
|
* associated with @type or %NULL if there is no #GTypeValueTable
|
||||||
|
* associated with @type
|
||||||
*/
|
*/
|
||||||
GTypeValueTable *
|
GTypeValueTable *
|
||||||
g_type_value_table_peek (GType type)
|
g_type_value_table_peek (GType type)
|
||||||
{
|
{
|
||||||
GTypeValueTable *vtable = NULL;
|
GTypeValueTable *vtable = NULL;
|
||||||
TypeNode *node = lookup_type_node_I (type);
|
TypeNode *node = lookup_type_node_I (type);
|
||||||
gboolean has_refed_data, has_table;
|
gboolean has_data, has_table;
|
||||||
|
|
||||||
if (node && NODE_REFCOUNT (node) && node->mutatable_check_cache)
|
if (node != NULL && node->mutatable_check_cache)
|
||||||
return node->data->common.value_table;
|
return node->data->common.value_table;
|
||||||
|
|
||||||
G_READ_LOCK (&type_rw_lock);
|
G_READ_LOCK (&type_rw_lock);
|
||||||
|
|
||||||
restart_table_peek:
|
restart_table_peek:
|
||||||
has_refed_data = node && node->data && NODE_REFCOUNT (node) > 0;
|
has_data = node != NULL && node->data != NULL;
|
||||||
has_table = has_refed_data && node->data->common.value_table->value_init;
|
has_table = has_data && node->data->common.value_table->value_init;
|
||||||
if (has_refed_data)
|
if (has_data)
|
||||||
{
|
{
|
||||||
if (has_table)
|
if (has_table)
|
||||||
vtable = node->data->common.value_table;
|
vtable = node->data->common.value_table;
|
||||||
@ -4391,7 +4157,7 @@ g_type_value_table_peek (GType type)
|
|||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
g_critical (G_STRLOC ": type id '%" G_GUINTPTR_FORMAT "' is invalid", (guintptr) type);
|
g_critical (G_STRLOC ": type id '%" G_GUINTPTR_FORMAT "' is invalid", (guintptr) type);
|
||||||
if (!has_refed_data)
|
if (!has_data)
|
||||||
g_critical ("can't peek value table for type '%s' which is not currently referenced",
|
g_critical ("can't peek value table for type '%s' which is not currently referenced",
|
||||||
type_descriptive_name_I (type));
|
type_descriptive_name_I (type));
|
||||||
|
|
||||||
@ -5039,7 +4805,7 @@ g_type_class_get_private (GTypeClass *klass,
|
|||||||
if (NODE_PARENT_TYPE (private_node))
|
if (NODE_PARENT_TYPE (private_node))
|
||||||
{
|
{
|
||||||
parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node));
|
parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node));
|
||||||
g_assert (parent_node->data && NODE_REFCOUNT (parent_node) > 0);
|
g_assert (parent_node->data);
|
||||||
|
|
||||||
if (G_UNLIKELY (private_node->data->class.class_private_size == parent_node->data->class.class_private_size))
|
if (G_UNLIKELY (private_node->data->class.class_private_size == parent_node->data->class.class_private_size))
|
||||||
{
|
{
|
||||||
|
@ -759,6 +759,8 @@ gboolean g_type_is_a (GType type,
|
|||||||
/* Hoist exact GType comparisons into the caller */
|
/* Hoist exact GType comparisons into the caller */
|
||||||
#define g_type_is_a(a,b) ((a) == (b) || (g_type_is_a) ((a), (b)))
|
#define g_type_is_a(a,b) ((a) == (b) || (g_type_is_a) ((a), (b)))
|
||||||
|
|
||||||
|
GOBJECT_AVAILABLE_IN_2_84
|
||||||
|
gpointer g_type_class_get (GType type);
|
||||||
GOBJECT_AVAILABLE_IN_ALL
|
GOBJECT_AVAILABLE_IN_ALL
|
||||||
gpointer g_type_class_ref (GType type);
|
gpointer g_type_class_ref (GType type);
|
||||||
GOBJECT_AVAILABLE_IN_ALL
|
GOBJECT_AVAILABLE_IN_ALL
|
||||||
@ -775,6 +777,8 @@ gpointer g_type_interface_peek (gpointer instance_
|
|||||||
GOBJECT_AVAILABLE_IN_ALL
|
GOBJECT_AVAILABLE_IN_ALL
|
||||||
gpointer g_type_interface_peek_parent (gpointer g_iface);
|
gpointer g_type_interface_peek_parent (gpointer g_iface);
|
||||||
|
|
||||||
|
GOBJECT_AVAILABLE_IN_2_84
|
||||||
|
gpointer g_type_default_interface_get (GType g_type);
|
||||||
GOBJECT_AVAILABLE_IN_ALL
|
GOBJECT_AVAILABLE_IN_ALL
|
||||||
gpointer g_type_default_interface_ref (GType g_type);
|
gpointer g_type_default_interface_ref (GType g_type);
|
||||||
GOBJECT_AVAILABLE_IN_ALL
|
GOBJECT_AVAILABLE_IN_ALL
|
||||||
|
Loading…
x
Reference in New Issue
Block a user