⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtype.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 5 页
字号:
      check_interface_info_I (iface, instance_type, &tmp_info);      iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));    }    return iholder;	/* we don't modify write lock upon returning NULL */}static voidtype_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);      G_WRITE_LOCK (&type_rw_lock);            type_data_unref_Wm (iface, FALSE);    }}/* --- type structure creation/destruction --- */GTypeInstance*g_type_create_instance (GType type){  TypeNode *node;  GTypeInstance *instance;  GTypeClass *class;  guint i;    node = lookup_type_node_I (type);  if (!node || !node->is_instantiatable)    {      g_warning ("cannot create new instance of invalid (non-instantiatable) type `%s'",		 type_descriptive_name_I (type));      return NULL;    }  /* G_TYPE_IS_ABSTRACT() is an external call: _U */  if (!node->mutatable_check_cache && G_TYPE_IS_ABSTRACT (type))    {      g_warning ("cannot create instance of abstract (non-instantiatable) type `%s'",		 type_descriptive_name_I (type));      return NULL;    }    class = g_type_class_ref (type);    if (node->data->instance.n_preallocs)    {      G_WRITE_LOCK (&type_rw_lock);      if (!node->data->instance.mem_chunk)	node->data->instance.mem_chunk = g_mem_chunk_new (NODE_NAME (node),							  node->data->instance.instance_size,							  (node->data->instance.instance_size *							   node->data->instance.n_preallocs),							  G_ALLOC_AND_FREE);      instance = g_chunk_new0 (GTypeInstance, node->data->instance.mem_chunk);      G_WRITE_UNLOCK (&type_rw_lock);    }  else    instance = g_malloc0 (node->data->instance.instance_size);	/* fine without read lock */  for (i = node->n_supers; i > 0; i--)    {      TypeNode *pnode;            pnode = lookup_type_node_I (node->supers[i]);      if (pnode->data->instance.instance_init)	{	  instance->g_class = pnode->data->instance.class;	  pnode->data->instance.instance_init (instance, class);	}    }  instance->g_class = class;    if (node->data->instance.instance_init)    node->data->instance.instance_init (instance, class);    return instance;}voidg_type_free_instance (GTypeInstance *instance){  TypeNode *node;  GTypeClass *class;    g_return_if_fail (instance != NULL && instance->g_class != NULL);    class = instance->g_class;  node = lookup_type_node_I (class->g_type);  if (!node || !node->is_instantiatable || !node->data || node->data->class.class != (gpointer) class)    {      g_warning ("cannot free instance of invalid (non-instantiatable) type `%s'",		 type_descriptive_name_I (class->g_type));      return;    }  /* G_TYPE_IS_ABSTRACT() is an external call: _U */  if (!node->mutatable_check_cache && G_TYPE_IS_ABSTRACT (NODE_TYPE (node)))    {      g_warning ("cannot free instance of abstract (non-instantiatable) type `%s'",		 NODE_NAME (node));      return;    }    instance->g_class = NULL;#ifdef G_ENABLE_DEBUG    memset (instance, 0xaa, node->data->instance.instance_size);	/* debugging hack */#endif    if (node->data->instance.n_preallocs)    {      G_WRITE_LOCK (&type_rw_lock);      g_chunk_free (instance, node->data->instance.mem_chunk);      G_WRITE_UNLOCK (&type_rw_lock);    }  else    g_free (instance);    g_type_class_unref (class);}static gbooleantype_iface_vtable_init_Wm (TypeNode *iface,			   TypeNode *node){  IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);  IFaceHolder *iholder;  GTypeInterface *vtable = NULL;  TypeNode *pnode;    /* 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), TRUE);  if (!iholder)    return FALSE;	/* we don't modify write lock upon FALSE */    g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info);    pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));  if (pnode)	/* want to copy over parent iface contents */    {      IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);            if (pentry)	vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size);    }  if (!vtable)    vtable = g_malloc0 (iface->data->iface.vtable_size);  entry->vtable = vtable;  vtable->g_type = NODE_TYPE (iface);  vtable->g_instance_type = NODE_TYPE (node);    if (iface->data->iface.vtable_init_base || iholder->info->interface_init)    {      G_WRITE_UNLOCK (&type_rw_lock);      if (iface->data->iface.vtable_init_base)	iface->data->iface.vtable_init_base (vtable);      if (iholder->info->interface_init)	iholder->info->interface_init (vtable, iholder->info->interface_data);      G_WRITE_LOCK (&type_rw_lock);    }  return TRUE;	/* write lock modified */}static gbooleantype_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;  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 voidtype_class_init_Wm (TypeNode   *node,		    GTypeClass *pclass){  GSList *slist, *init_slist = NULL;  GTypeClass *class;  IFaceEntry *entry;  TypeNode *bnode, *pnode;  guint i;    g_assert (node->is_classed && node->data &&	    node->data->class.class_size &&	    !node->data->class.class);    class = g_malloc0 (node->data->class.class_size);  node->data->class.class = class;    if (pclass)    {      TypeNode *pnode = lookup_type_node_I (pclass->g_type);            memcpy (class, pclass, pnode->data->class.class_size);    }  class->g_type = NODE_TYPE (node);    G_WRITE_UNLOCK (&type_rw_lock);    /* stack all base class initialization functions, so we   * call them in ascending order.   */  for (bnode = node; bnode; bnode = lookup_type_node_I (NODE_PARENT_TYPE (bnode)))    if (bnode->data->class.class_init_base)      init_slist = g_slist_prepend (init_slist, (gpointer) bnode->data->class.class_init_base);  for (slist = init_slist; slist; slist = slist->next)    {      GBaseInitFunc class_init_base = (GBaseInitFunc) slist->data;            class_init_base (class);    }  g_slist_free (init_slist);    if (node->data->class.class_init)    node->data->class.class_init (class, (gpointer) node->data->class.class_data);    G_WRITE_LOCK (&type_rw_lock);    /* ok, we got the class done, now initialize all interfaces, either   * from parent, or through our holder info   */  pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));  entry = CLASSED_NODE_IFACES_ENTRIES (node) + 0;  while (entry)    {      g_assert (entry->vtable == NULL);            if (!type_iface_vtable_init_Wm (lookup_type_node_I (entry->iface_type), node))	{	  guint j;	  	  /* type_iface_vtable_init_Wm() doesn't modify write lock upon FALSE,	   * need to get this interface from parent	   */	  g_assert (pnode != NULL);	  	  for (j = 0; j < CLASSED_NODE_N_IFACES (pnode); j++)	    {	      IFaceEntry *pentry = CLASSED_NODE_IFACES_ENTRIES (pnode) + j;	      	      if (pentry->iface_type == entry->iface_type)		{		  entry->vtable = pentry->vtable;		  break;		}	    }	  g_assert (entry->vtable != NULL);	}            /* refetch entry, IFACES_ENTRIES might be modified */      for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)	if (!CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable)	  entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;    }}static voidtype_data_finalize_class_ifaces_Wm (TypeNode *node){  IFaceEntry *entry;  guint i;    g_assert (node->is_instantiatable && node->data && node->data->class.class && node->data->common.ref_count == 0);    g_message ("finalizing interfaces for %sClass `%s'",	     type_descriptive_name_I (NODE_FUNDAMENTAL_TYPE (node)),	     type_descriptive_name_I (NODE_TYPE (node)));    for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)    if (CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable &&	CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable->g_instance_type == NODE_TYPE (node))      entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;  while (entry)    {      if (!type_iface_vtable_finalize_Wm (lookup_type_node_I (entry->iface_type), node, entry->vtable))	{	  /* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE,	   * iface vtable came from parent	   */	  entry->vtable = NULL;	}            /* refetch entry, IFACES_ENTRIES might be modified */      for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)	if (CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable &&	    CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable->g_instance_type == NODE_TYPE (node))	  entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;    }}static voidtype_data_finalize_class_U (TypeNode  *node,			    ClassData *cdata){  GTypeClass *class = cdata->class;  TypeNode *bnode;    g_assert (cdata->class && cdata->common.ref_count == 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);    class->g_type = 0;  g_free (cdata->class);}static voidtype_data_last_unref_Wm (GType    type,			 gboolean uncached){  TypeNode *node = lookup_type_node_I (type);    g_return_if_fail (node != NULL && node->plugin != NULL);    if (!node->data || node->data->common.ref_count == 0)    {      g_warning ("cannot drop last reference to unreferenced type `%s'",		 type_descriptive_name_I (type));      return;    }    if (node->is_classed && node->data && node->data->class.class && static_n_class_cache_funcs)    {      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->data->common.ref_count == 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);    }    if (node->data->common.ref_count > 1)	/* may have been re-referenced meanwhile */    node->data->common.ref_count -= 1;  else    {      GType ptype = NODE_PARENT_TYPE (node);      TypeData *tdata;            node->data->common.ref_count = 0;            if (node->is_instantiatable && node->data->instance.mem_chunk)	{	  g_mem_chunk_destroy (node->data->instance.mem_chunk);	  node->data->instance.mem_chunk = NULL;	}            tdata = node->data;      if (node->is_classed && tdata->class.class)	{	  if (CLASSED_NODE_N_IFACES (node))	    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	{	  node->mutatable_check_cache = FALSE;	  node->data = NULL;	}            /* freeing tdata->common.value_table and its contents is taking care of

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -