glib interface implement mechanism analysis, what mean the offsets field of TypeNode structure?
zhang007z
zhang007z at gmail.com
Fri Oct 23 00:35:17 PDT 2015
recently I search glib a part of interface implement mechanism, I have mainly
purpose that I can better learn gstreamer library by searching glib .
so I confuse that glib offsets field of _TypeNode structure.
struct _TypeNode
{
guint volatile ref_count;
#ifdef G_ENABLE_DEBUG
guint volatile instance_count;
#endif
GTypePlugin *plugin;
guint n_children; /* writable with lock */
guint n_supers : 8;
guint n_prerequisites : 9;
guint is_classed : 1;
guint is_instantiatable : 1;
guint mutatable_check_cache : 1; /* combines some common path
checks */
GType *children; /* writable with lock */
TypeData * volatile data;
GQuark qname;
GData *global_gdata;
union {
GAtomicArray iface_entries; /* for !iface types */
GAtomicArray offsets;
} _prot;
GType *prerequisites;
GType supers[1]; /* flexible array */
};
first issue: iface_entries store the interface class of class in union
_prot. according to _IFaceEntries structure, see as below structure:
struct _IFaceEntries {
guint offset_index;
IFaceEntry entry[1];
};
I know that entry[1] store momery space for new interface class,this
entry[1] could increase.but I don't understand that what does offset_index
field mean? (I guess that offset_index is IFaceEntry sum of entry[1],but
this speculate likely is wrong. )
second issue: offsets feild of union _prot of interface class TypeNode is
used to interface class. what does offsets feild mean?
as follow code:
//---------------------------------------------------------------------------//
static void
type_node_add_iface_entry_W (TypeNode *node,
GType iface_type,
IFaceEntry *parent_entry)
{
IFaceEntries *entries;
IFaceEntry *entry;
TypeNode *iface_node;
guint i, j;
int num_entries;
g_assert (node->is_instantiatable);
entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
if (entries != NULL)
{
num_entries = IFACE_ENTRIES_N_ENTRIES (entries);
g_assert (num_entries < MAX_N_INTERFACES);
for (i = 0; i < num_entries; i++)
{
entry = &entries->entry[i];
if (entry->iface_type == iface_type)
{
/* this can happen in two cases:
* - our parent type already conformed to iface_type and node
* got its own holder info. here, our children already have
* entries and NULL vtables, since this will only work for
* uninitialized classes.
* - an interface type is added to an ancestor after it was
* added to a child type.
*/
if (!parent_entry)
g_assert (entry->vtable == NULL && entry->init_state == UNINITIALIZED);
else
{
/* sick, interface is added to ancestor *after* child type;
* nothing todo, the entry and our children were already setup correctly
*/
}
return;
}
}
}
entries = _g_atomic_array_copy (CLASSED_NODE_IFACES_ENTRIES (node),
IFACE_ENTRIES_HEADER_SIZE,
sizeof (IFaceEntry));//zhang007z,新增一个IFaceEntry
的元素到(node)->_prot.iface_entries中
num_entries = IFACE_ENTRIES_N_ENTRIES (entries);
i = num_entries - 1;
if (i == 0)
entries->offset_index = 0;
entries->entry[i].iface_type = iface_type;
entries->entry[i].vtable = NULL;
entries->entry[i].init_state = UNINITIALIZED;
if (parent_entry)
{
if (node->data && node->data->class.init_state >= BASE_IFACE_INIT)
{
entries->entry[i].init_state = INITIALIZED;
entries->entry[i].vtable = parent_entry->vtable;
}
}
/* Update offsets in iface */
iface_node = lookup_type_node_I (iface_type);
if (iface_node_has_available_offset_L (iface_node,
entries->offset_index,
i))
{
iface_node_set_offset_L (iface_node,
entries->offset_index, i);
}
else
{
entries->offset_index =
find_free_iface_offset_L (entries);
for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (entries); j++)
{
entry = &entries->entry[j];
iface_node =
lookup_type_node_I (entry->iface_type);
iface_node_set_offset_L (iface_node,
entries->offset_index, j);
}
}
_g_atomic_array_update (CLASSED_NODE_IFACES_ENTRIES (node), entries);
if (parent_entry)
{
for (i = 0; i < node->n_children; i++)
type_node_add_iface_entry_W (lookup_type_node_I (node->children[i]),
iface_type, &entries->entry[i]);
}
}
//---------------------------------------------------------------------------//
I don't understand below part of code:
if (iface_node_has_available_offset_L (iface_node,
entries->offset_index,
i))
{
iface_node_set_offset_L (iface_node,
entries->offset_index, i);
}
else
{
entries->offset_index =
find_free_iface_offset_L (entries);
for (j = 0; j < IFACE_ENTRIES_N_ENTRIES (entries); j++)
{
entry = &entries->entry[j];
iface_node =
lookup_type_node_I (entry->iface_type);
iface_node_set_offset_L (iface_node,
entries->offset_index, j);
}
}
//-------------------------------------------------------------------------------//
by reading this code ,I guess that offset_index feild of union _prot of
instantiable class TypeNode likely exist certain relation to offsets feild
of union _prot of interface class TypeNode. find_free_iface_offset_L
function that I don't understand .
Anybody have any idea for me. thank you for spending your time to my issue.
--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/glib-interface-implement-mechanism-analysis-what-mean-the-offsets-field-of-TypeNode-structure-tp4674222.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
More information about the gstreamer-devel
mailing list