📄 pils.c
字号:
/* Call the registration function for our interface type */ rc = ifops->RegisterInterface(ifinfo, Imports); /* Increment reference count of interface manager */ IfIncrRefCount(ifmgrinfo, 1); /* Increment the ref count of the plugin that loaded us */ PluginIncrRefCount(piinfo, 1); if (rc != PIL_OK) { RemoveAPILInterface(ifinfo); } return rc;}/* * Method: * * Verify interface is valid. * * Call interface close function. * * Call interface manager unregister function * * Call RmAPILInterface to remove from InterfaceType table, and * free interface object. * */static PIL_rcPILunregister_interface(PILInterface* id){ PILInterfaceType* t; PILInterfaceUniv* u; PIL_rc rc; PILInterface* ifmgr_info; /* Pointer to our interface handler */ const PILInterfaceOps* exports; /* InterfaceManager operations for * the type of interface we are */ if ( id == NULL || (t = id->interfacetype) == NULL || (u = t->universe) == NULL || id->interfacename == NULL || id->if_close == NULL) { PILLog(PIL_WARN, "PILunregister_interface: bad interfaceid"); return PIL_INVAL; } if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "PILunregister_interface(%s/%s)" , t->typename, id->interfacename); } PILValidateInterface(NULL, id, t); PILValidateInterfaceType(NULL, t, u); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "Calling InterfaceClose on %s/%s" , t->typename, id->interfacename); } /* Call the close function supplied by the interface */ if ((rc=id->if_close(id, id->ud_interface)) != PIL_OK) { PILLog(PIL_WARN, "InterfaceClose on %s/%s returned %s" , t->typename, id->interfacename , PIL_strerror(rc)); } /* Find the InterfaceManager that manages us */ ifmgr_info = t->ifmgr_ref; g_assert(ifmgr_info != NULL); /* Find the exported functions from that IFIF */ exports = ifmgr_info->exports; g_assert(exports != NULL && exports->UnRegisterInterface != NULL); /* Call the interface manager unregister function */ exports->UnRegisterInterface(id); /* Decrement reference count of interface manager */ IfIncrRefCount(ifmgr_info, -1); /* This may make ifmgr_info invalid */ ifmgr_info = NULL; /* Decrement the reference count of the plugin that loaded us */ PluginIncrRefCount(id->loadingpi, -1); return rc;}static PILInterfaceUniv*NewPILInterfaceUniv(PILPluginUniv* piuniv){ PILInterfaceUniv* ret = NEW(PILInterfaceUniv); static int ltinityet = 0; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "NewPILInterfaceUniv(0x%x)" , (unsigned long)ret); } if (!ltinityet) { ltinityet=1; lt_dlinit(); } STATNEW(interfaceuniv); ret->MagicNum = PIL_MAGIC_INTERFACEUNIV; /* Make the two universes point at each other */ ret->piuniv = piuniv; piuniv->ifuniv = ret; ret->iftypes = g_hash_table_new(g_str_hash, g_str_equal); InterfaceManager_plugin_init(piuniv); return ret;}static voidDelPILInterfaceUniv(PILInterfaceUniv* ifuniv){ PILInterfaceType* ifmgrtype; g_assert(ifuniv!= NULL && ifuniv->iftypes != NULL); PILValidateInterfaceUniv(NULL, ifuniv, NULL); STATFREE(interfaceuniv); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "DelPILInterfaceUniv(0x%lx)" , (unsigned long) ifuniv); } g_hash_table_foreach_remove(ifuniv->iftypes, RmAPILInterfaceType, NULL); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "DelPILInterfaceUniv: final cleanup"); } ifmgrtype = g_hash_table_lookup(ifuniv->iftypes, PI_IFMANAGER); RemoveAPILInterfaceType(ifmgrtype, ifmgrtype); /* * FIXME! need to delete the interface for PI_IFMANAGER last * Right now, it seems to happen last, but I think that's * coincidence... */ g_hash_table_destroy(ifuniv->iftypes); ZAP(ifuniv); DELETE(ifuniv);}/* * 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 /* IsA GHFunc: required for g_hash_table_foreach_remove() */RmAPILInterfaceType( gpointer typename /* Name of this interface type */, gpointer iftype /* PILInterfaceType* */, gpointer notused){ PILInterfaceType* Iftype = iftype; PILInterfaceUniv* Ifuniv = Iftype->universe; /* * We are not always called by g_hash_table_foreach_remove() */ g_assert(IS_PILINTERFACETYPE(Iftype)); PILValidateInterfaceUniv(NULL, Ifuniv, NULL); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "RmAPILInterfaceType(%s)" , (char*)typename); } if (iftype != notused && strcmp(Iftype->typename, PI_IFMANAGER) == 0) { if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "RmAPILInterfaceType: skipping (%s)" , (char*)typename); } return FALSE; } DelPILInterfaceType(iftype); DELETE(typename); return TRUE;}static voidRemoveAPILInterfaceType(PILInterfaceType*Iftype, PILInterfaceType* t2){ PILInterfaceUniv* Ifuniv = Iftype->universe; gpointer key; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "RemoveAPILInterfaceType(%s)" , Iftype->typename); } if (t2 != Iftype && strcmp(Iftype->typename, PI_IFMANAGER) == 0) { PILLog(PIL_DEBUG, "RemoveAPILInterfaceType: skipping (%s)" , Iftype->typename); return; } if (g_hash_table_lookup_extended(Ifuniv->iftypes , Iftype->typename, &key, (gpointer)&Iftype)) { g_hash_table_remove(Ifuniv->iftypes, key); RmAPILInterfaceType(key, Iftype, t2); }else{ g_assert_not_reached(); }}/* * We need to write more functions: These include... * * Plugin functions: * * PILPluginPath() - returns path name for a given plugin * * PILPluginTypeList() - returns list of plugins of a given type * */static void free_dirlist(struct dirent** dlist, int n);static int qsort_string_cmp(const void *a, const void *b);static voidfree_dirlist(struct dirent** dlist, int n){ int j; for (j=0; j < n; ++j) { if (dlist[j]) { free(dlist[j]); dlist[j] = NULL; } } free(dlist);}static intqsort_string_cmp(const void *a, const void *b){ return(strcmp(*(const char * const *)a, *(const char * const *)b));}#define FREE_DIRLIST(dlist, n) {free_dirlist(dlist, n); dlist = NULL;}static intso_select (const struct dirent *dire){ const char obj_end [] = PLUGINSUFFIX; const char *end = &dire->d_name[strlen(dire->d_name) - (STRLEN(obj_end))]; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "In so_select: %s.", dire->d_name); } if (obj_end < dire->d_name) { return 0; } if (strcmp(end, obj_end) == 0) { if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "FILE %s looks like a plugin name." , dire->d_name); } return 1; } if (DEBUGPLUGIN) { PILLog(PIL_DEBUG , "FILE %s Doesn't look like a plugin name [%s] " "%d %d %s." , dire->d_name, end , sizeof(obj_end), strlen(dire->d_name) , &dire->d_name[strlen(dire->d_name) - (sizeof(obj_end)-1)]); } return 0;}/* Return (sorted) list of available plugin names */static char**PILPluginTypeListPlugins(PILPluginType* pitype, int * picount /* Can be NULL ... */){ const char * piclass = pitype->plugintype; unsigned plugincount = 0; char ** result = NULL; int initoff = 0; char ** pelem; /* Return all the plugins in all the directories in the PATH */ for (pelem=pitype->piuniv->rootdirlist; *pelem; ++pelem) { int j; GString* path; int dircount; struct dirent** files; path = g_string_new(*pelem); g_assert(piclass != NULL); if (piclass) { if (g_string_append_c(path, G_DIR_SEPARATOR) == NULL || g_string_append(path, piclass) == NULL) { g_string_free(path, 1); path = NULL; return(NULL); } } files = NULL; errno = 0; dircount = scandir(path->str, &files , SCANSEL_CAST so_select, NULL); g_string_free(path, 1); path=NULL; if (dircount <= 0) { if (files != NULL) { FREE_DIRLIST(files, dircount); files = NULL; } continue; } initoff = plugincount; plugincount += dircount; if (result == NULL) { result = (char **) g_malloc((plugincount+1)*sizeof(char *)); }else{ result = (char **) g_realloc(result , (plugincount+1)*sizeof(char *)); } for (j=0; j < dircount; ++j) { char* s; unsigned slen = strlen(files[j]->d_name) - STRLEN(PLUGINSUFFIX); s = g_malloc(slen+1); strncpy(s, files[j]->d_name, slen); s[slen] = EOS; result[initoff+j] = s; } FREE_DIRLIST(files, dircount); files = NULL; } if (picount != NULL) { *picount = plugincount; } if (result) { result[plugincount] = NULL; /* Return them in sorted order... */ qsort(result, plugincount, sizeof(char *), qsort_string_cmp); } return result;}/* Return (sorted) list of available plugin names */char**PILListPlugins(PILPluginUniv* u, const char * pitype, int * picount /* Can be NULL ... */){ PILPluginType* t; if ((t = g_hash_table_lookup(u->PluginTypes, pitype)) == NULL) { if (picount) { *picount = 0; } t = NewPILPluginType(u, pitype); if (!t) { return NULL; } } return PILPluginTypeListPlugins(t, picount);}voidPILFreePluginList(char ** pluginlist){ char ** ml = pluginlist; if (!ml) { return; } while (*ml != NULL) { DELETE(*ml); } DELETE(pluginlist);}static voidPILValidatePlugin(gpointer key, gpointer plugin, gpointer pitype){ const char * Key = key; const PILPlugin * Plugin = plugin; g_assert(IS_PILPLUGIN(Plugin)); g_assert(Key == NULL || strcmp(Key, Plugin->plugin_name) == 0); g_assert (Plugin->refcnt >= 0 ); /* g_assert (Plugin->pluginops != NULL ); */ g_assert (strcmp(Key, PI_IFMANAGER) == 0 || Plugin->dlinitfun != NULL ); g_assert (strcmp(Plugin->plugin_name, PI_IFMANAGER) == 0 || Plugin->dlhandle != NULL); g_assert(Plugin->plugintype != NULL); g_assert(IS_PILPLUGINTYPE(Plugin->plugintype)); g_assert(pitype == NULL || pitype == Plugin->plugintype);}static voidPILValidatePluginType(gpointer key, gpointer pitype, gpointer piuniv){ char * Key = key; PILPluginType * Pitype = pitype; PILPluginUniv * Muniv = piuniv; g_assert(IS_PILPLUGINTYPE(Pitype)); g_assert(Muniv == NULL || IS_PILPLUGINUNIV(Muniv)); g_assert(Key == NULL || strcmp(Key, Pitype->plugintype) == 0); g_assert(IS_PILPLUGINUNIV(Pitype->piuniv)); g_assert(piuniv == NULL || piuniv == Pitype->piuniv); g_assert(Pitype->Plugins != NULL); g_hash_table_foreach(Pitype->Plugins, PILValidatePlugin, Pitype);}static voidPILValidatePluginUniv(gpointer key, gpointer piuniv, gpointer dummy){ PILPluginUniv * Muniv = piuniv; g_assert(IS_PILPLUGINUNIV(Muniv)); g_assert(Muniv->rootdirlist != NULL); g_assert(Muniv->imports != NULL); g_hash_table_foreach(Muniv->PluginTypes, PILValidatePluginType, piuniv); PILValidateInterfaceUniv(NULL, Muniv->ifuniv, piuniv);}static voidPILValidateInterface(gpointer key, gpointer interface, gpointer iftype){ char * Key = key; PILInterface* Interface = interface; g_assert(IS_PILINTERFACE(Interface)); g_assert(Key == NULL || strcmp(Key, Interface->interfacename) == 0); g_assert(IS_PILINTERFACETYPE(Interface->interfacetype)); g_assert(iftype == NULL || iftype == Interface->interfacetype); g_assert(Interface->ifmanager!= NULL); g_assert(IS_PILINTERFACE(Interface->ifmanager)); g_assert(strcmp(Interface->interfacetype->typename , Interface->ifmanager->interfacename)== 0); g_assert(Interface->exports != NULL); g_assert(Interface->if_close != NULL);}static voidPILValidateInterfaceType(gpointer key, gpointer iftype, gpointer ifuniv){ char * Key = key; PILInterfaceType* Iftype = iftype; g_assert(IS_PILINTERFACETYPE(Iftype)); g_assert(Key == NULL || strcmp(Key, Iftype->typename) == 0); g_assert(ifuniv == NULL || Iftype->universe == ifuniv); g_assert(Iftype->interfaces != NULL); g_assert(Iftype->ifmgr_ref != NULL); g_assert(IS_PILINTERFACE(Iftype->ifmgr_ref)); g_assert(Key == NULL || strcmp(Key, Iftype->ifmgr_ref->interfacename) == 0); g_hash_table_foreach(Iftype->interfaces, PILValidateInterface, iftype);}static voidPILValidateInterfaceUniv(gpointer key, gpointer ifuniv, gpointer piuniv){ PILInterfaceUniv* Ifuniv = ifuniv; PILPluginUniv* Pluginuniv = piuniv; g_assert(IS_PILINTERFACEUNIV(Ifuniv)); g_assert(Pluginuniv == NULL || IS_PILPLUGINUNIV(Pluginuniv)); g_assert(piuniv == NULL || piuniv == Ifuniv->piuniv); g_hash_table_foreach(Ifuniv->iftypes, PILValidateInterfaceType, ifuniv);}#define PRSTAT(type) { \ PILLog(PIL_INFO, "Plugin system objects (" #type "): " \ "\tnew %ld free \%ld current %ld" \ , PILstats.type.news \ , PILstats.type.frees \ , PILstats.type.news - PILstats.type.frees); \}voidPILLogMemStats(void){ PRSTAT(plugin); PRSTAT(pitype); PRSTAT(piuniv); PRSTAT(interface); PRSTAT(interfacetype); PRSTAT(interfaceuniv);}/* * Function for logging with the given logging function * The reason why it's here is so we can get printf arg checking * You can't get that when you call a function pointer directly. */voidPILCallLog(PILLogFun logfun, PILLogLevel priority, const char * fmt, ...){ va_list args; char * str; va_start (args, fmt); str = g_strdup_vprintf(fmt, args); va_end (args); logfun(priority, "%s", str); g_free(str);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -