?? pils.c
字號:
{ return eifinfo->refcnt;} /* Modify the reference count for this interface */static intIfIncrRefCount(PILInterface*eifinfo, int plusminus){ if(DEBUGPLUGIN) { PILLog(PIL_DEBUG, "IfIncrRefCount(%d + %d )" , eifinfo->refcnt, plusminus); } eifinfo->refcnt += plusminus; if (eifinfo->refcnt <= 0) { eifinfo->refcnt = 0; /* Unregister this interface. */ RemoveAPILInterface(eifinfo); return 0; } return eifinfo->refcnt;}#if 0static intPluginRefCount(PILPlugin * pi){ return pi->refcnt;}#endifstatic intPluginIncrRefCount(PILPlugin*pi, int plusminus){ if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "PluginIncrRefCount(%d + %d )" , pi->refcnt, plusminus); } pi->refcnt += plusminus; if (pi->refcnt <= 0) { pi->refcnt = 0; RemoveAPILPlugin(pi); return 0; } return pi->refcnt;}static PILInterface*FindIF(PILPluginUniv* universe, const char *iftype, const char * ifname){ PILInterfaceUniv* puniv; PILInterfaceType* ptype; if (universe == NULL || (puniv = universe->ifuniv) == NULL || (ptype=g_hash_table_lookup(puniv->iftypes, iftype))==NULL){ return NULL; } return g_hash_table_lookup(ptype->interfaces, ifname);}PIL_rc PILIncrIFRefCount(PILPluginUniv* mu, const char * interfacetype, const char * interfacename, int plusminus){ PILInterface* intf = FindIF(mu, interfacetype, interfacename); if (intf) { g_assert(IS_PILINTERFACE(intf)); IfIncrRefCount(intf, plusminus); return PIL_OK; } return PIL_NOPLUGIN;}intPILGetIFRefCount(PILPluginUniv* mu, const char * interfacetype, const char * interfacename){ PILInterface* intf = FindIF(mu, interfacetype, interfacename); return IfRefCount(intf);}static voidIfForceUnregister(PILInterface *id){ if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "IfForceUnRegister(%s)" , id->interfacename); } RemoveAPILInterface(id);}struct f_e_c_helper { gboolean(*fun)(PILInterface* clientif, void * passalong); void* passalong;};static gboolean IfForEachClientHelper(gpointer key, gpointer iftype, gpointer helper_v);static gbooleanIfForEachClientHelper(gpointer unused, gpointer iftype, gpointer v){ struct f_e_c_helper* s = (struct f_e_c_helper*)v; g_assert(IS_PILINTERFACE((PILInterface*)iftype)); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "IfForEachClientHelper(%s)" , ((PILInterface*)iftype)->interfacename); } return s->fun((PILInterface*)iftype, s->passalong);}static voidIfForEachClientRemove( PILInterface* mgrif, gboolean(*f)(PILInterface* clientif, void * passalong), void* passalong /* usually PILInterface* */){ PILInterfaceType* mgrt; PILInterfaceUniv* u; const char * ifname; PILInterfaceType* clientt; struct f_e_c_helper h = {f, passalong}; if (mgrif == NULL || (mgrt = mgrif->interfacetype) == NULL || (u = mgrt->universe) == NULL || (ifname = mgrif->interfacename) == NULL) { PILLog(PIL_WARN, "bad parameters to IfForEachClientRemove"); return; } if ((clientt = g_hash_table_lookup(u->iftypes, ifname)) == NULL) { if (DEBUGPLUGIN) { PILLog(PIL_DEBUG , "Interface manager [%s/%s] has no clients" , PI_IFMANAGER, ifname); } return; }; if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "IfForEachClientRemove(%s:%s)" , mgrt->typename, clientt->typename); } if (clientt->ifmgr_ref != mgrif) { PILLog(PIL_WARN, "Bad ifmgr_ref ptr in PILInterfaceType"); return; } g_hash_table_foreach_remove(clientt->interfaces, IfForEachClientHelper , &h);}static PIL_rcPILregister_plugin(PILPlugin* piinfo, const PILPluginOps* commonops){ piinfo->pluginops = commonops; return PIL_OK;}static PIL_rcPILunregister_plugin(PILPlugin* piinfo){ if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "PILunregister_plugin(%s)" , piinfo->plugin_name); } RemoveAPILPlugin(piinfo); return PIL_OK;}/* General logging function (not really UPPILS-specific) */static voidPILLog(PILLogLevel priority, const char * format, ...){ va_list args; GLogLevelFlags flags; switch(priority) { case PIL_FATAL: flags = G_LOG_LEVEL_ERROR; break; case PIL_CRIT: flags = G_LOG_LEVEL_CRITICAL; break; default: /* FALL THROUGH... */ case PIL_WARN: flags = G_LOG_LEVEL_WARNING; break; case PIL_INFO: flags = G_LOG_LEVEL_INFO; break; case PIL_DEBUG: flags = G_LOG_LEVEL_DEBUG; break; }; va_start (args, format); g_logv (G_LOG_DOMAIN, flags, format, args); va_end (args);}static const char * PIL_strerrmsgs [] ={ "Success", "Invalid Parameters", "Bad plugin/interface type", "Duplicate entry (plugin/interface name/type)", "Oops happens", "No such plugin/interface/interface type"};const char *PIL_strerror(PIL_rc rc){ int irc = (int) rc; static char buf[128]; if (irc < 0 || irc >= DIMOF(PIL_strerrmsgs)) { snprintf(buf, sizeof(buf), "return code %d (?)", irc); return buf; } return PIL_strerrmsgs[irc];}/* * Returns the PATHname of the file containing the requested plugin * This file handles PATH-like semantics from the rootdirlist. * It is also might be the right place to put alias handing in the future... */static char *PILPluginPath(PILPluginUniv* universe, const char * plugintype, const char * pluginname){ char * PluginPath = NULL; char ** spath_component; for (spath_component = universe->rootdirlist; *spath_component ; ++ spath_component) { if (PluginPath) { g_free(PluginPath); PluginPath=NULL; } PluginPath = g_strdup_printf("%s%s%s%s%s%s" , *spath_component , G_DIR_SEPARATOR_S , plugintype , G_DIR_SEPARATOR_S , pluginname , PLUGINSUFFIX); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG , "PILS: Looking for %s/%s => [%s]" , plugintype, pluginname, PluginPath); } if (PluginExists(PluginPath) == PIL_OK) { if (DEBUGPLUGIN) { PILLog(PIL_DEBUG , "Plugin path for %s/%s => [%s]" , plugintype, pluginname, PluginPath); } return PluginPath; } /* FIXME: Put alias file processing here... */ } /* Can't find 'em all... */ return PluginPath;}static PIL_rcPluginExists(const char * PluginPath){ /* Make sure we can read and execute the plugin file */ /* This test is nice, because dlopen reasons aren't return codes */ if (access(PluginPath, R_OK) != 0) { if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "Plugin file %s does not exist" , PluginPath); } return PIL_NOPLUGIN; } return PIL_OK;}/* Return PIL_OK if the given plugin exists */PIL_rcPILPluginExists(PILPluginUniv* piuniv, const char * plugintype, const char * pluginname){ PIL_rc rc; char * path = PILPluginPath(piuniv, plugintype, pluginname); if (path == NULL) { return PIL_INVAL; } rc = PluginExists(path); DELETE(path); return rc;}/* * PILLoadPlugin() - loads a plugin into memory and calls the * initial() entry point in the plugin. * * * Method: * * Construct file name of plugin. * See if plugin exists. If not, fail with PIL_NOPLUGIN. * * Search Universe for plugin type * If found, search plugin type for pluginname * if found, fail with PIL_EXIST. * Otherwise, * Create new Plugin type structure * Use lt_dlopen() on plugin to get lt_dlhandle for it. * * Construct the symbol name of the initialization function. * * Use lt_dlsym() to find the pointer to the init function. * * Call the initialization function. */PIL_rcPILLoadPlugin(PILPluginUniv* universe, const char * plugintype, const char * pluginname, void* plugin_user_data){ PIL_rc rc; char * PluginPath; char * PluginSym; PILPluginType* pitype; PILPlugin* piinfo; lt_dlhandle dlhand; PILPluginInitFun initfun; PluginPath = PILPluginPath(universe, plugintype, pluginname); if ((rc=PluginExists(PluginPath)) != PIL_OK) { DELETE(PluginPath); return rc; } if((pitype=g_hash_table_lookup(universe->PluginTypes, plugintype)) != NULL) { if ((piinfo = g_hash_table_lookup ( pitype->Plugins, pluginname)) != NULL) { if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "Plugin %s already loaded" , PluginPath); } DELETE(PluginPath); return PIL_EXIST; } if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "PluginType %s already present" , plugintype); } }else{ if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "Creating PluginType for %s" , plugintype); } /* Create a new PILPluginType object */ pitype = NewPILPluginType(universe, plugintype); } g_assert(pitype != NULL); /* * At this point, we have a PILPluginType object and our * plugin name is not listed in it. */ dlhand = lt_dlopen(PluginPath); if (!dlhand) { PILLog(PIL_WARN , "lt_dlopen() failure on plugin %s/%s [%s]." " Reason: [%s]" , plugintype, pluginname , PluginPath , lt_dlerror()); DELETE(PluginPath); return PIL_NOPLUGIN; } DELETE(PluginPath); /* Construct the magic init function symbol name */ PluginSym = g_strdup_printf(PIL_FUNC_FMT , plugintype, pluginname); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "Plugin %s/%s init function: %s" , plugintype, pluginname , PluginSym); } initfun = lt_dlsym(dlhand, PluginSym); if (initfun == NULL) { PILLog(PIL_WARN , "Plugin %s/%s init function (%s) not found" , plugintype, pluginname, PluginSym); DELETE(PluginSym); lt_dlclose(dlhand); dlhand=NULL; DelPILPluginType(pitype); return PIL_NOPLUGIN; } DELETE(PluginSym); /* * Construct the new PILPlugin object */ piinfo = NewPILPlugin(pitype, pluginname, dlhand, initfun); g_assert(piinfo != NULL); g_hash_table_insert(pitype->Plugins, g_strdup(piinfo->plugin_name), piinfo); if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "Plugin %s/%s loaded and constructed." , plugintype, pluginname); } if (DEBUGPLUGIN) { PILLog(PIL_DEBUG, "Calling init function in plugin %s/%s." , plugintype, pluginname); } /* Save away the user_data for later */ piinfo->ud_plugin = plugin_user_data; /* initfun is allowed to change ud_plugin if they want */ initfun(piinfo, universe->imports, plugin_user_data); return PIL_OK;}/*PILLoadPlugin*/#define REPORTERR(msg) PILLog(PIL_CRIT, "%s", msg)/* * Register an interface. * * This function is exported to plugins for their use. */static PIL_rcPILRegisterInterface(PILPlugin* piinfo, const char * interfacetype /* Type of interface */, const char * interfacename /* Name of interface */, void* Ops /* Info (functions) exported by this interface */, PILInterfaceFun close_func /* Close function for interface */, PILInterface** interfaceid /* Interface id (OP) */, void** Imports /* Functions imported by this interface (OP) */, void* ud_interface /* Optional user_data */){ PILPluginUniv* piuniv; /* Universe this plugin is in */ PILPluginType* pitype; /* Type of this plugin */ PILInterfaceUniv* ifuniv; /* Universe this interface is in */ PILInterfaceType*iftype; /* Type of this interface */ PILInterface* ifinfo; /* Info about this Interface */ PILInterfaceType*ifmgrtype; /* PILInterfaceType for PI_IFMANAGER */ PILInterface* ifmgrinfo; /* Interf info for "interfacetype" */ const PILInterfaceOps* ifops; /* Ops vector for InterfaceManager */ /* of type "interfacetype" */ PIL_rc rc; if ( piinfo == NULL || (pitype = piinfo->plugintype) == NULL || (piuniv = pitype->piuniv) == NULL || (ifuniv = piuniv->ifuniv) == NULL || ifuniv->iftypes == NULL ) { REPORTERR("bad parameters to PILRegisterInterface"); return PIL_INVAL; } /* Now we have lots of info, but not quite enough... */ if ((iftype = g_hash_table_lookup(ifuniv->iftypes, interfacetype)) == NULL) { /* Try to autoload the needed interface handler */ rc = PILLoadPlugin(piuniv, PI_IFMANAGER, interfacetype, NULL); /* See if the interface handler loaded like we expect */ if ((iftype = g_hash_table_lookup(ifuniv->iftypes , interfacetype)) == NULL) { return PIL_BADTYPE; } } if ((ifinfo = g_hash_table_lookup(iftype->interfaces, interfacename)) != NULL) { g_warning("Attempt to register duplicate interface: %s/%s" , interfacetype, interfacename); return PIL_EXIST; } /* * OK... Now we know it is valid, and isn't registered... * Let's locate the InterfaceManager registrar for this type */ if ((ifmgrtype = g_hash_table_lookup(ifuniv->iftypes, PI_IFMANAGER)) == NULL) { REPORTERR("No " PI_IFMANAGER " type!"); return PIL_OOPS; } if ((ifmgrinfo = g_hash_table_lookup(ifmgrtype->interfaces , interfacetype)) == NULL) { PILLog(PIL_CRIT , "No interface manager for given type (%s) !" , interfacetype); return PIL_BADTYPE; } ifops = ifmgrinfo->exports; /* Now we have all the information anyone could possibly want ;-) */ ifinfo = NewPILInterface(iftype, interfacename, Ops , close_func, ud_interface, piinfo); g_assert(ifmgrinfo == ifinfo->ifmanager); *interfaceid = ifinfo; /* Call the registration function for our interface type */ rc = ifops->RegisterInterface(ifinfo, Imports); /* Increment reference count of interface manager */ IfIncrRefCount(ifmgrinfo, 1);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -