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

📄 generic.c

📁 linux集群服务器软件代码包
💻 C
字号:
/* $Id: generic.c,v 1.23 2004/10/06 10:55:17 lars Exp $ *//* *  * Generic interface (implementation) manager * * Copyright 2001 Alan Robertson <alanr@unix.sh> * Licensed under the GNU Lesser General Public License * * This manager will manage any number of types of interfaces. * * This means that when any implementations of our client interfaces register * or unregister, it is us that makes their interfaces show up in the outside * world. * * And, of course, we have to do this in a very generic way, since we have * no idea about the client programs or interface types, or anything else. * * We do that by getting a parameter passed to us which tell us the names * of the interface types we want to manage, and the address of a GHashTable * for each type that we put the implementation in when they register * themselves. * * So, each type of interface that we manage gets its own private * GHashTable of the implementations of that type that are currently * registered. * * For example, if we manage communication modules, their exported * interfaces will be registered in a hash table.  If we manage * authentication modules, they'll have their (separate) hash table that * their exported interfaces are registered in. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#define	PIL_PLUGINTYPE		InterfaceMgr#define PIL_PLUGINTYPE_S	"InterfaceMgr"#define	PIL_PLUGIN		generic#define PIL_PLUGIN_S		"generic"#define PIL_PLUGINLICENSE	LICENSE_LGPL#define PIL_PLUGINLICENSEURL	URL_LGPL/* We are an interface manager... */#define ENABLE_PLUGIN_MANAGER_PRIVATE#define ENABLE_PIL_DEFS_PRIVATE#include <portability.h>#include <pils/generic.h>#include <stdio.h>PIL_PLUGIN_BOILERPLATE("1.0", GenDebugFlag, CloseGeneralPluginManager)/* * Key is interface type, value is a PILGenericIfMgmtRqst. * The key is g_strdup()ed, but the struct is not copied. */static gboolean FreeAKey(gpointer key, gpointer value, gpointer data);/* *	Places to store information gotten during registration. */static const PILPluginImports*	GenPIImports;	/* Imported plugin fcns */static PILPlugin*		GenPlugin;	/* Our plugin info */static PILInterfaceImports*	GenIfImports;	/* Interface imported fcns *//* Our exported generic interface management functions */static PIL_rc RegisterGenIF(PILInterface* ifenv, void**	imports);static PIL_rc UnregisterGenIF(PILInterface*iifinfo);static PIL_rc CloseGenInterfaceManager(PILInterface*, void* info);/* *	Our Interface Manager interfaces - exported to the universe! * *	(or at least to the interface management universe ;-). * *	These are the interfaces which are used to manage our *	client implementations */static PILInterfaceOps		GenIfOps ={	RegisterGenIF,	UnregisterGenIF};PIL_rc PIL_PLUGIN_INIT(PILPlugin*us, PILPluginImports* imports, void*);/* *	Our user_ptr is presumed to point to NULL-terminated array of *	PILGenericIfMgmtRqst structs. * *	These requests have pointers to GHashTables for us *	to put plugins into when they show up, and drop from when *	they disappear. * * 	Issues include: * 	- freeing all memory, * 	- making sure things are all cleaned up correctly * 	- Thread-safety? * * 	IMHO the global system should handle thread-safety. */static PIL_rc AddAnInterfaceType(PILPlugin*us, GHashTable* MasterTable, PILGenericIfMgmtRqst* req);PIL_rcPIL_PLUGIN_INIT(PILPlugin*us, PILPluginImports* imports, void *user_ptr){	PIL_rc			ret;	PILGenericIfMgmtRqst*	user_req;	PILGenericIfMgmtRqst*	curreq;	GHashTable*	MasterTable = NULL;	/*	 * Force the compiler to check our parameters...	 */	PILPluginInitFun	fun = &PIL_PLUGIN_INIT; (void)fun;	GenPIImports = imports;	if (GenDebugFlag) {		PILCallLog(GenPIImports->log, PIL_DEBUG		,	"IF manager %s: initializing.", PIL_PLUGIN_S);	}	if (user_ptr == NULL) {		PILCallLog(GenPIImports->log, PIL_CRIT		,	"%s Interface Manager requires non-NULL "		" PILGenericIfMgmtRqst user pointer at initialization."		,	PIL_PLUGIN_S);		return PIL_INVAL;	}	GenPlugin = us;	if (GenDebugFlag) {		PILCallLog(GenPIImports->log, PIL_DEBUG		,	"IF manager %s: registering as a plugin."		, PIL_PLUGIN_S);	}	user_req = user_ptr;	MasterTable = g_hash_table_new(g_str_hash, g_str_equal);	us->ud_plugin = MasterTable;	/* Override passed value */	/* Register ourselves as a plugin */	if ((ret = imports->register_plugin(us, &OurPIExports)) != PIL_OK) {		PILCallLog(imports->log, PIL_CRIT		,	"IF manager %s unable to register as plugin (%s)"		,	PIL_PLUGIN_S, PIL_strerror(ret));		return ret;	}	/*	 * Register to manage implementations	 * for all the interface types we've been asked to manage.	 */	for(curreq = user_req; curreq->iftype != NULL; ++curreq) {		PIL_rc newret;		newret = AddAnInterfaceType(us, MasterTable, curreq);		if (newret != PIL_OK) {			ret = newret;		}	}	/*	 * Our plugin and all our registered plugin types	 * have ud_plugin pointing at MasterTable.	 */	return ret;}static PIL_rcAddAnInterfaceType(PILPlugin*us, GHashTable* MasterTable, PILGenericIfMgmtRqst* req){	PIL_rc	rc;	PILInterface*		GenIf;		/* Our Generic Interface info*/	g_assert(MasterTable != NULL);	g_hash_table_insert(MasterTable, g_strdup(req->iftype), req);	if (req->ifmap == NULL) {		PILCallLog(GenPIImports->log, PIL_CRIT		,	"IF manager %s: iftype %s has NULL"		" ifmap pointer address."		,	PIL_PLUGIN_S, req->iftype);		return PIL_INVAL;	}	if ((*req->ifmap) != NULL) {		PILCallLog(GenPIImports->log, PIL_CRIT		,	"IF manager %s: iftype %s GHashTable pointer"		" was not initialized to NULL"		,	PIL_PLUGIN_S, req->iftype);		return PIL_INVAL;	}	if (GenDebugFlag) {		PILCallLog(GenPIImports->log, PIL_DEBUG		,	"IF manager %s: registering ourselves"		" to manage interface type %s"		,	PIL_PLUGIN_S, req->iftype);		PILCallLog(GenPIImports->log, PIL_DEBUG		,	"%s IF manager: ifmap: 0x%lx callback: 0x%lx"		" imports: 0x%lx"		,	PIL_PLUGIN_S		,	(unsigned long)req->ifmap		,	(unsigned long)req->callback		,	(unsigned long)req->importfuns);	}	/* Create the hash table to communicate with this client */	*(req->ifmap) = g_hash_table_new(g_str_hash, g_str_equal);	rc = GenPIImports->register_interface(us	,	PIL_PLUGINTYPE_S	,	req->iftype	/* the iftype we're managing here */	,	&GenIfOps	,	CloseGenInterfaceManager	,	&GenIf	,	(void*)&GenIfImports	,	MasterTable);	/* Point ud_interface to MasterTable */	/* We don't ever want to be unloaded... */	GenIfImports->ModRefCount(GenIf, +100);	if (rc != PIL_OK) {		PILCallLog(GenPIImports->log, PIL_CRIT		,	"Generic interface manager %s: unable to register"		" to manage interface type %s: %s"		,	PIL_PLUGIN_S, req->iftype		,	PIL_strerror(rc));	}	return rc;}static voidCloseGeneralPluginManager(PILPlugin* us){		GHashTable*	MasterTable = us->ud_plugin;	int		count;	g_assert(MasterTable != NULL);	/*	 * All our clients have already been shut down automatically	 * This is the final shutdown for us...	 */	/* There *shouldn't* be any keys in there ;-) */	if ((count=g_hash_table_size(MasterTable)) > 0) {		/* But just in case there are... */		g_hash_table_foreach_remove(MasterTable, FreeAKey, NULL);	}	g_hash_table_destroy(MasterTable);	us->ud_plugin = NULL;	return;}/* *	We get called for every time an implementation registers itself as *	implementing one of the kinds of interfaces we manage. * *	It's our job to make the implementation that's *	registering with us available to the system. * *	We do that by adding it to a GHashTable for its interface type *	Our users in the rest of the system takes it from there... * *	The key to the GHashTable is the implementation name, and the data is *	a pointer to the information the implementation exports. * *	It's a piece of cake ;-) */static PIL_rcRegisterGenIF(PILInterface* intf,  void** imports){	PILGenericIfMgmtRqst*	ifinfo;	GHashTable*	MasterTable = intf->ifmanager->ud_interface;	g_assert(MasterTable != NULL);	/* Reference count should now be one */	if (GenDebugFlag) {		PILCallLog(GenPIImports->log, PIL_DEBUG		,	"%s IF manager: interface %s/%s registering."		,	PIL_PLUGIN_S, intf->interfacetype->typename		,	intf->interfacename);	}	g_assert(intf->refcnt == 1);	/*	 * We need to add it to the table that goes with this particular	 * type of interface.	 */	if ((ifinfo = g_hash_table_lookup(MasterTable	,	intf->interfacetype->typename)) !=	NULL)	{		GHashTable*		ifmap = *(ifinfo->ifmap);		g_hash_table_insert(ifmap, intf->interfacename,intf->exports);		if (GenDebugFlag) {			PILCallLog(GenPIImports->log, PIL_DEBUG			, "%s IF manager: Inserted interface [%s] in hash"			" table @ 0x%08lx"			, PIL_PLUGIN_S, intf->interfacename			, (unsigned long)ifmap);			PILCallLog(GenPIImports->log, PIL_DEBUG			, "%s IF manager: Exports are here: 0x%08x"			, PIL_PLUGIN_S			, GPOINTER_TO_UINT(intf->exports));		}		if (ifinfo->callback != NULL) {			PILInterfaceType*	t = intf->interfacetype;			if (GenDebugFlag) {				PILCallLog(GenPIImports->log, PIL_DEBUG				,	"%s IF manager: callback 0x%lx"				,	PIL_PLUGIN_S				,	(unsigned long)ifinfo->callback);			}			ifinfo->callback(PIL_REGISTER			,	t->universe->piuniv, intf->interfacename			,	t->typename, ifinfo->userptr);		}		*imports = ifinfo->importfuns;		return PIL_OK;	}else{		PILCallLog(GenPIImports->log, PIL_WARN		,	"RegisterGenIF: interface type %s not found"		,	intf->interfacename);	}	return PIL_INVAL;}/* Unregister an implementation - * 	We get called from the interface management system when someone * 	has requested that an implementation of a client interface be * 	unregistered. */static PIL_rcUnregisterGenIF(PILInterface*intf){	GHashTable*	MasterTable = intf->ifmanager->ud_interface;	PILGenericIfMgmtRqst*	ifinfo;	g_assert(MasterTable != NULL);	g_assert(intf->refcnt >= 0);	/*	 * Go through the "master table" and find client table, 	 * notify client we're about to remove this entry, then	 * then remove this entry from it.	 */	if (GenDebugFlag) {		PILCallLog(GenPIImports->log, PIL_DEBUG		,	"%s IF manager: unregistering interface %s/%s."		,	PIL_PLUGIN_S, intf->interfacetype->typename		,	intf->interfacename);	}	if ((ifinfo = g_hash_table_lookup(MasterTable	,	intf->interfacetype->typename)) != NULL)	{		GHashTable*		ifmap = *(ifinfo->ifmap);		if (ifinfo->callback != NULL) {			PILInterfaceType*	t = intf->interfacetype;			if (GenDebugFlag) {				PILCallLog(GenPIImports->log, PIL_DEBUG				,	"%s IF manager: callback 0x%lx"				,	PIL_PLUGIN_S				,	(unsigned long)ifinfo->callback);			}			ifinfo->callback(PIL_UNREGISTER			,	t->universe->piuniv, intf->interfacename			,	t->typename, ifinfo->userptr);		}		/* Remove the client entry from master table */		g_hash_table_remove(ifmap, intf->interfacename);	}else{		PILCallLog(GenPIImports->log, PIL_WARN		,	"UnregisterGenIF: interface type %s not found"		,	intf->interfacename);		return PIL_INVAL;	}	return PIL_OK;}/* *	Close down the generic interface manager. */static PIL_rcCloseGenInterfaceManager(PILInterface*intf, void* info){	void*		key;	void*		data;	GHashTable*	MasterTable = intf->ud_interface;	if (GenDebugFlag) {		PILCallLog(GenPIImports->log, PIL_INFO		,	"In CloseGenInterFaceManager on %s/%s (MasterTable: 0x%08lx)"		,	intf->interfacetype->typename, intf->interfacename		,	(unsigned long)MasterTable);	}	g_assert(MasterTable != NULL);	if (g_hash_table_lookup_extended(MasterTable	,	intf->interfacename, &key, &data)) {		PILGenericIfMgmtRqst*	ifinfo = data;		g_hash_table_destroy(*(ifinfo->ifmap));		*(ifinfo->ifmap) = NULL;		g_hash_table_remove(MasterTable, key);		g_free(key);	}else{		g_assert_not_reached();	}	return PIL_OK;}static gbooleanFreeAKey(gpointer key, gpointer value, gpointer data){	g_free(key);	return TRUE;}

⌨️ 快捷键说明

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