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