/* --- structures --- */
struct _TypeNode
{
- guint volatile ref_count;
+ guint ref_count; /* (atomic) */
#ifdef G_ENABLE_DEBUG
- guint volatile instance_count;
+ guint instance_count; /* (atomic) */
#endif
GTypePlugin *plugin;
guint n_children; /* writable with lock */
guint is_instantiatable : 1;
guint mutatable_check_cache : 1; /* combines some common path checks */
GType *children; /* writable with lock */
- TypeData * volatile data;
+ TypeData *data;
GQuark qname;
GData *global_gdata;
union {
};
struct _IFaceEntries {
- guint offset_index;
+ gsize offset_index;
IFaceEntry entry[1];
};
CommonData common;
guint16 class_size;
guint16 class_private_size;
- int volatile init_state; /* atomic - g_type_class_ref reads it unlocked */
+ int init_state; /* (atomic) - g_type_class_ref reads it unlocked */
GBaseInitFunc class_init_base;
GBaseFinalizeFunc class_finalize_base;
GClassInitFunc class_init;
CommonData common;
guint16 class_size;
guint16 class_private_size;
- int volatile init_state; /* atomic - g_type_class_ref reads it unlocked */
+ int init_state; /* (atomic) - g_type_class_ref reads it unlocked */
GBaseInitFunc class_init_base;
GBaseFinalizeFunc class_finalize_base;
GClassInitFunc class_init;
node = G_STRUCT_MEMBER_P (node, SIZEOF_FUNDAMENTAL_INFO);
static_fundamental_type_nodes[ftype >> G_TYPE_FUNDAMENTAL_SHIFT] = node;
type = ftype;
+
+#if ENABLE_VALGRIND
+ VALGRIND_MALLOCLIKE_BLOCK (node, node_size - SIZEOF_FUNDAMENTAL_INFO, FALSE, TRUE);
+#endif
}
else
type = (GType) node;
}
static inline IFaceEntry*
-lookup_iface_entry_I (volatile IFaceEntries *entries,
- TypeNode *iface_node)
+lookup_iface_entry_I (IFaceEntries *entries,
+ TypeNode *iface_node)
{
guint8 *offsets;
- guint offset_index;
+ gsize offset_index;
IFaceEntry *check;
- int index;
+ gsize index;
IFaceEntry *entry;
if (entries == NULL)
static gboolean
iface_node_has_available_offset_L (TypeNode *iface_node,
- int offset,
+ gsize offset,
int for_index)
{
guint8 *offsets;
return FALSE;
}
-static int
+static gsize
find_free_iface_offset_L (IFaceEntries *entries)
{
IFaceEntry *entry;
TypeNode *iface_node;
- int offset;
+ gsize offset;
int i;
int n_entries;
n_entries = IFACE_ENTRIES_N_ENTRIES (entries);
- offset = -1;
+ offset = 0;
do
{
- offset++;
for (i = 0; i < n_entries; i++)
{
entry = &entries->entry[i];
iface_node = lookup_type_node_I (entry->iface_type);
if (!iface_node_has_available_offset_L (iface_node, offset, i))
- break;
+ {
+ offset++;
+ break;
+ }
}
}
while (i != n_entries);
static void
iface_node_set_offset_L (TypeNode *iface_node,
- int offset,
+ gsize offset,
int index)
{
guint8 *offsets, *old_offsets;
- int new_size, old_size;
- int i;
+ gsize new_size, old_size;
+ gsize i;
old_offsets = G_ATOMIC_ARRAY_GET_LOCKED (&iface_node->_prot.offsets, guint8);
if (old_offsets == NULL)
IFaceEntry *entry;
TypeNode *iface_node;
guint i, j;
- int num_entries;
+ guint num_entries;
g_assert (node->is_instantiatable);
if (parent_entry)
{
- if (node->data && node->data->class.init_state >= BASE_IFACE_INIT)
+ if (node->data && g_atomic_int_get (&node->data->class.init_state) >= BASE_IFACE_INIT)
{
entries->entry[i].init_state = INITIALIZED;
entries->entry[i].vtable = parent_entry->vtable;
iholder->next = iface_node_get_holders_L (iface);
iface_node_set_holders_W (iface, iholder);
iholder->instance_type = NODE_TYPE (node);
- iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
+ iholder->info = info ? g_memdup2 (info, sizeof (*info)) : NULL;
iholder->plugin = plugin;
/* create an iface entry for this type */
*/
if (node->data)
{
- InitState class_state = node->data->class.init_state;
+ InitState class_state = g_atomic_int_get (&node->data->class.init_state);
if (class_state >= BASE_IFACE_INIT)
type_iface_vtable_base_init_Wm (iface, node);
}
}
- for (i = 0; i < prerequisite_node->n_supers + 1; i++)
+ for (i = 0; i < prerequisite_node->n_supers + 1u; i++)
type_iface_add_prerequisite_W (iface, lookup_type_node_I (prerequisite_node->supers[i]));
G_WRITE_UNLOCK (&type_rw_lock);
}
}
}
+/**
+ * g_type_interface_instantiatable_prerequisite:
+ * @interface_type: an interface type
+ *
+ * Returns the most specific instantiatable prerequisite of an
+ * interface type. If the interface type has no instantiatable
+ * prerequisite, %G_TYPE_INVALID is returned.
+ *
+ * See g_type_interface_add_prerequisite() for more information
+ * about prerequisites.
+ *
+ * Returns: the instantiatable prerequisite type or %G_TYPE_INVALID if none
+ *
+ * Since: 2.68
+ **/
+GType
+g_type_interface_instantiatable_prerequisite (GType interface_type)
+{
+ TypeNode *inode = NULL;
+ TypeNode *iface;
+ guint i;
+
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), G_TYPE_INVALID);
+
+ iface = lookup_type_node_I (interface_type);
+ if (iface == NULL)
+ return G_TYPE_INVALID;
+
+ G_READ_LOCK (&type_rw_lock);
+
+ for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
+ {
+ GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
+ TypeNode *node = lookup_type_node_I (prerequisite);
+ if (node->is_instantiatable)
+ {
+ if (!inode || type_node_is_a_L (node, inode))
+ inode = node;
+ }
+ }
+
+ G_READ_UNLOCK (&type_rw_lock);
+
+ if (inode)
+ return NODE_TYPE (inode);
+ else
+ return G_TYPE_INVALID;
+}
static IFaceHolder*
type_iface_peek_holder_L (TypeNode *iface,
INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface));
check_interface_info_I (iface, instance_type, &tmp_info);
- iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
+ iholder->info = g_memdup2 (&tmp_info, sizeof (tmp_info));
}
return iholder; /* we don't modify write lock upon returning NULL */
IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);
if (pentry)
- vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size);
+ vtable = g_memdup2 (pentry->vtable, iface->data->iface.vtable_size);
}
if (!vtable)
- vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
+ vtable = g_memdup2 (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
entry->vtable = vtable;
vtable->g_type = NODE_TYPE (iface);
vtable->g_instance_type = NODE_TYPE (node);
TypeNode *bnode, *pnode;
guint i;
- /* Accessing data->class will work for instantiable types
+ /* Accessing data->class will work for instantiatable types
* too because ClassData is a subset of InstanceData
*/
g_assert (node->is_classed && node->data &&
node->data->class.class_size &&
!node->data->class.class &&
- node->data->class.init_state == UNINITIALIZED);
+ g_atomic_int_get (&node->data->class.init_state) == UNINITIALIZED);
if (node->data->class.class_private_size)
class = g_malloc0 (ALIGN_STRUCT (node->data->class.class_size) + node->data->class.class_private_size);
else
* inherited interfaces are already init_state == INITIALIZED, because
* they either got setup in the above base_init loop, or during
* class_init from within type_add_interface_Wm() for this or
- * an anchestor type.
+ * an ancestor type.
*/
i = 0;
while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL)
/**
* g_type_add_interface_static:
- * @instance_type: #GType value of an instantiable type
+ * @instance_type: #GType value of an instantiatable type
* @interface_type: #GType value of an interface type
* @info: #GInterfaceInfo structure for this
* (@instance_type, @interface_type) combination
*
- * Adds @interface_type to the static @instantiable_type.
+ * Adds @interface_type to the static @instance_type.
* The information contained in the #GInterfaceInfo structure
* pointed to by @info is used to manage the relationship.
*/
/**
* g_type_add_interface_dynamic:
- * @instance_type: #GType value of an instantiable type
+ * @instance_type: #GType value of an instantiatable type
* @interface_type: #GType value of an interface type
* @plugin: #GTypePlugin structure to retrieve the #GInterfaceInfo from
*
- * Adds @interface_type to the dynamic @instantiable_type. The information
+ * Adds @interface_type to the dynamic @instance_type. The information
* contained in the #GTypePlugin structure pointed to by @plugin
* is used to manage the relationship.
*/
* @root_type: immediate parent of the returned type
*
* Given a @leaf_type and a @root_type which is contained in its
- * anchestry, return the type that @root_type is the immediate parent
+ * ancestry, return the type that @root_type is the immediate parent
* of. In other words, this function determines the type that is
* derived directly from @root_type which is also a base class of
* @leaf_type. Given a root type and a leaf type, this function can
* be used to determine the types and order in which the leaf type is
* descended from the root type.
*
- * Returns: immediate child of @root_type and anchestor of @leaf_type
+ * Returns: immediate child of @root_type and ancestor of @leaf_type
*/
GType
g_type_next_base (GType type,
/**
* g_type_is_a:
- * @type: type to check anchestry for
- * @is_a_type: possible anchestor of @type or interface that @type
+ * @type: type to check ancestry for
+ * @is_a_type: possible ancestor of @type or interface that @type
* could conform to
*
* If @is_a_type is a derivable type, check whether @type is a