📄 pils.c
字号:
* so they have gpointer arguments. This *not necessarily* clause * is why they do the g_hash_table_lookup_extended call instead of * just deleting the key. When called from outside, the key * * may not be pointing at the key to actually free, but a copy * of the key. */static gboolean /* IsA GHFunc: required for g_hash_table_foreach_remove() */RmAPILPluginType( gpointer pitname /* Name of this plugin type "real" key */, gpointer pitype /* PILPluginType* */, gpointer notused){ PILPluginType* Plugintype = pitype; g_assert(IS_PILPLUGINTYPE(Plugintype)); PILValidatePluginType(pitname, pitype, NULL); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "RmAPILPluginType(%s)" , Plugintype->plugintype); } /* * This function is usually but not always called by * g_hash_table_foreach_remove() */ DelPILPluginType(pitype); DELETE(pitname); return TRUE;} static voidRemoveAPILPluginType(PILPluginType*Plugintype){ PILPluginUniv* Pluginuniv = Plugintype->piuniv; gpointer key; if (g_hash_table_lookup_extended(Pluginuniv->PluginTypes , Plugintype->plugintype, &key, (void*)&Plugintype)) { g_hash_table_remove(Pluginuniv->PluginTypes, key); RmAPILPluginType(key, Plugintype, NULL); }else{ g_assert_not_reached(); }}/* * InterfaceManager_plugin_init: Initialize the handling of * "Interface Manager" interfaces. * * There are a few potential bootstraiffng problems here ;-) * */static PIL_rcInterfaceManager_plugin_init(PILPluginUniv* univ){ PILPluginImports* imports = univ->imports; PILPluginType* pitype; PILInterface* ifinfo; PILInterfaceType* iftype; void* dontcare; PILPlugin* ifmgr_plugin; PIL_rc rc; iftype = NewPILInterfaceType(univ->ifuniv, PI_IFMANAGER, &IfExports , NULL); g_hash_table_insert(univ->ifuniv->iftypes , g_strdup(PI_IFMANAGER), iftype); pitype = NewPILPluginType(univ, PI_IFMANAGER); g_hash_table_insert(univ->PluginTypes , g_strdup(PI_IFMANAGER), pitype); ifmgr_plugin= NewPILPlugin(pitype, PI_IFMANAGER, NULL, NULL); g_hash_table_insert(pitype->Plugins , g_strdup(PI_IFMANAGER), ifmgr_plugin); /* We can call register_plugin, since it doesn't depend on us... */ rc = imports->register_plugin(ifmgr_plugin, &PluginExports); if (rc != PIL_OK) { PILLog(PIL_CRIT, "register_plugin() failed in init: %s" , PIL_strerror(rc)); return(rc); } /* * Now, we're registering interfaces, and are into some deep * Catch-22 if do it the "easy" way, since our code is * needed in order to support interface loading for the type of * interface we are (a Interface interface). * * So, instead of calling imports->register_interface(), we have to * do the work ourselves here... * * Since no one should yet be registered to handle Interface * interfaces, we need to bypass the hash table handler lookup * that register_interface would do and call the function that * register_interface would call... * */ /* The first argument is the PILInterfaceType* */ ifinfo = NewPILInterface(iftype, PI_IFMANAGER, &IfExports , close_ifmgr_interface, NULL, NULL); ifinfo->ifmanager = iftype->ifmgr_ref = ifinfo; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "InterfaceManager_plugin_init(0x%lx/%s)" , (unsigned long)ifinfo, ifinfo->interfacename); } PILValidatePluginUniv(NULL, univ, NULL); ifmgr_register_interface(ifinfo, &dontcare); PILValidatePluginUniv(NULL, univ, NULL); return(PIL_OK);}/*InterfaceManager_plugin_init*//* Return current IfIf "plugin" version (not very interesting for us) */static const char *PIL_PILPluginVersion(void){ return("1.0");}/* Return current IfIf debug level */intPILpisysGetDebugLevel(void){ return(PluginDebugLevel);}/* Set current IfIf debug level */voidPILpisysSetDebugLevel (int level){ PluginDebugLevel = level;}struct set_debug_helper { const char * pitype; const char * piname; int level;};static voidPILSetDebugLeveltoPlugin(gpointer key, gpointer plugin, gpointer Helper){ PILPlugin* p = plugin; struct set_debug_helper* helper = Helper; p->pluginops->setdebuglevel(helper->level); }static voidPILSetDebugLevelbyType(const void * key, gpointer plugintype, gpointer Helper){ struct set_debug_helper* helper = Helper; PILPluginType* t = plugintype; if (helper->piname == NULL) { g_hash_table_foreach(t->Plugins, PILSetDebugLeveltoPlugin , helper); }else{ PILPlugin* p = g_hash_table_lookup(t->Plugins , helper->piname); if (p != NULL) { p->pluginops->setdebuglevel(helper->level); } }}voidPILSetDebugLevel(PILPluginUniv* u, const char * pitype, const char * piname, int level){ struct set_debug_helper helper = {pitype, piname, level}; if (u == NULL) { return; } if (pitype == NULL) { g_hash_table_foreach(u->PluginTypes /* * Reason for this next cast: * SetDebugLevelbyType takes const gpointer * arguments, unlike a GHFunc which doesn't. */ , (GHFunc)PILSetDebugLevelbyType , &helper); }else{ PILPluginType* t = g_hash_table_lookup(u->PluginTypes , pitype); if (t != NULL) { PILSetDebugLevelbyType(pitype, t, &helper); } }}intPILGetDebugLevel(PILPluginUniv* u, const char * pitype, const char * piname){ PILPluginType* t; PILPlugin* p; if ( u == NULL || pitype == NULL || (t = g_hash_table_lookup(u->PluginTypes, pitype)) == NULL || (p = g_hash_table_lookup(t->Plugins, piname)) == NULL) { return -1; } return p->pluginops->getdebuglevel();}/* Close/shutdown our PILPlugin (the interface manager interface plugin) *//* All our interfaces will have already been shut down and unregistered */static voidPIL_PILPluginClose (PILPlugin* plugin){}static const char *PIL_PILPluginLicense (void){ return LICENSE_LGPL;}static const char *PIL_PILPluginLicenseUrl (void){ return URL_LGPL;}/***************************************************************************** * * This code is for managing interfaces, and interacting with them... * ****************************************************************************/static PILInterface*NewPILInterface(PILInterfaceType* interfacetype , const char* interfacename , void * exports , PILInterfaceFun closefun , void* ud_interface , PILPlugin* loading_plugin){ PILInterface* ret = NULL; PILInterface* look = NULL; if ((look = g_hash_table_lookup(interfacetype->interfaces , interfacename)) != NULL) { PILLog(PIL_DEBUG, "Deleting PILInterface!"); DelPILInterface(look); } ret = NEW(PILInterface); STATNEW(interface); ret->MagicNum = PIL_MAGIC_INTERFACE; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "NewPILInterface(0x%x)", (unsigned long)ret); } if (ret) { ret->interfacetype = interfacetype; ret->exports = exports; ret->ud_interface = ud_interface; ret->interfacename = g_strdup(interfacename); ret->ifmanager = interfacetype->ifmgr_ref; ret->loadingpi = loading_plugin; g_hash_table_insert(interfacetype->interfaces , g_strdup(ret->interfacename), ret); ret->if_close = closefun; ret->refcnt = 1; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "NewPILInterface(0x%lx:%s/%s)*** user_data: 0x%lx *******" , (unsigned long)ret , interfacetype->typename , ret->interfacename , ud_interface); } } return ret;}static voidDelPILInterface(PILInterface* intf){ if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "DelPILInterface(0x%lx/%s)" , (unsigned long)intf, intf->interfacename); } STATFREE(interface); DELETE(intf->interfacename); ZAP(intf); DELETE(intf);}static PILInterfaceType*NewPILInterfaceType(PILInterfaceUniv*univ, const char * typename, void* ifeports, void* user_data){ PILInterfaceType* ifmgr_types; PILInterface* ifmgr_ref; PILInterfaceType* ret = NEW(PILInterfaceType); STATNEW(interfacetype); ret->MagicNum = PIL_MAGIC_INTERFACETYPE; ret->typename = g_strdup(typename); ret->interfaces = g_hash_table_new(g_str_hash, g_str_equal); ret->ud_if_type = user_data; ret->universe = univ; ret->ifmgr_ref = NULL; /* Now find the pointer to our if type in the Interface Universe */ if ((ifmgr_types = g_hash_table_lookup(univ->iftypes, PI_IFMANAGER)) != NULL) { if ((ifmgr_ref=g_hash_table_lookup(ifmgr_types->interfaces , typename)) != NULL) { ret->ifmgr_ref = ifmgr_ref; }else { g_assert(strcmp(typename, PI_IFMANAGER) == 0); } }else { g_assert(strcmp(typename, PI_IFMANAGER) == 0); } /* Insert ourselves into our parent's table */ g_hash_table_insert(univ->iftypes, g_strdup(typename), ret); return ret;}static voidDelPILInterfaceType(PILInterfaceType*ift){ PILInterfaceUniv* u = ift->universe; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "DelPILInterfaceType(%s)" , ift->typename); } STATFREE(interfacetype); PILValidateInterfaceUniv(NULL, u, NULL); /* * RmAPILInterface refuses to remove the interface for the * Interface manager, because it must be removed last. * * Otherwise we won't be able to unregister interfaces * for other types of objects, and we'll be very confused. */ g_hash_table_foreach_remove(ift->interfaces, RmAPILInterface, NULL); PILValidateInterfaceUniv(NULL, u, NULL); if (g_hash_table_size(ift->interfaces) > 0) { gpointer key, iftype; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG , "DelPILInterfaceType(%s): table size (%d)" , ift->typename, g_hash_table_size(ift->interfaces)); } if (g_hash_table_lookup_extended(ift->interfaces , PI_IFMANAGER, &key, &iftype)) { DelPILInterface((PILInterface*)iftype); DELETE(key); } } DELETE(ift->typename); g_hash_table_destroy(ift->interfaces); ZAP(ift); DELETE(ift);}/* * These RmA* functions primarily called from hash_table_foreach, * so they have gpointer arguments. This *not necessarily* clause * is why they do the g_hash_table_lookup_extended call instead of * just deleting the key. When called from outside, the key * * may not be pointing at the key to actually free, but a copy * of the key. */static gboolean /* IsAGHFunc: required for g_hash_table_foreach_remove() */RmAPILInterface( gpointer ifname /* Name of this interface */, gpointer intf /* PILInterface* */, gpointer notused){ PILInterface* If = intf; PILInterfaceType* Iftype = If->interfacetype; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "RmAPILInterface(0x%lx/%s)" , (unsigned long)If, If->interfacename); } g_assert(IS_PILINTERFACE(If)); /* * Don't remove the master interface manager this way, or * Somebody will have a cow... */ if (If == If->ifmanager) { if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "RmAPILInterface: skipping (%s)" , If->interfacename); } return FALSE; } PILValidateInterface(ifname, If, Iftype); PILValidateInterfaceType(NULL, Iftype, NULL); /* * This function is usually but not always called by * g_hash_table_foreach_remove() */ PILunregister_interface(If); PILValidateInterface(ifname, If, Iftype); PILValidateInterfaceType(NULL, Iftype, NULL); DELETE(ifname); DelPILInterface(If); return TRUE;}static PIL_rcRemoveAPILInterface(PILInterface* pif){ PILInterfaceType* Iftype = pif->interfacetype; gpointer key; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "RemoveAPILInterface(0x%lx/%s)" , (unsigned long)pif, pif->interfacename); } if (g_hash_table_lookup_extended(Iftype->interfaces , pif->interfacename, &key, (void*)&pif)) { g_assert(IS_PILINTERFACE(pif)); g_hash_table_remove(Iftype->interfaces, key); RmAPILInterface(key, pif, NULL); }else{ g_assert_not_reached(); } if (g_hash_table_size(Iftype->interfaces) == 0) { /* The generic plugin handler doesn't want us to * delete it's types... */ if (Iftype->ifmgr_ref->refcnt <= 1) { RemoveAPILInterfaceType(Iftype, NULL); } } return PIL_OK;}/* Register a Interface Interface (Interface manager) */static PIL_rcifmgr_register_interface(PILInterface* intf, void** imports){ PILInterfaceType* ift = intf->interfacetype; PILInterfaceUniv* ifuniv = ift->universe; PILInterfaceOps* ifops; /* Ops vector for InterfaceManager */ if (DEBUGPLUGIN) { PILLog(PIL_DEBUG , "Registering Implementation manager for" " Interface type '%s'" , intf->interfacename); } ifops = intf->exports; if (ifops->RegisterInterface == NULL || ifops->UnRegisterInterface == NULL) { PILLog(PIL_DEBUG, "ifmgr_register_interface(%s)" ": NULL exported function pointer" , intf->interfacename); return PIL_INVAL; } *imports = &IFManagerImports; if(g_hash_table_lookup(ifuniv->iftypes, intf->interfacename) == NULL){ /* It registers itself into ifuniv automatically */ NewPILInterfaceType(ifuniv,intf->interfacename, &IfExports , NULL); } return PIL_OK;}static gbooleanRemoveAllClients(PILInterface*interface, void * managerif){ /* * Careful! We can't remove ourselves this way... * This gets taken care of as a special case in DelPILInterfaceUniv... */ if (managerif == interface) { return FALSE; } PILunregister_interface(interface); return TRUE;}/* Unconditionally unregister a interface manager (InterfaceMgr Interface) */static PIL_rcifmgr_unregister_interface(PILInterface* interface){ /* * We need to unregister every interface we manage */ if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "ifmgr_unregister_interface(%s)" , interface->interfacename); } IfForEachClientRemove(interface, RemoveAllClients, interface); return PIL_OK;}/* Called to close the Interface manager for type Interface */static PIL_rcclose_ifmgr_interface(PILInterface* us, void* ud_interface){ if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "close_ifmgr_interface(%s)" , us->interfacename); } /* Nothing much to do */ return PIL_OK;}/* Return the reference count for this interface */static intIfRefCount(PILInterface * eifinfo)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -