Plugin project proposal

Nicolas Williams Nicolas.Williams at oracle.com
Fri Jul 16 15:20:25 EDT 2010


On Fri, Jul 16, 2010 at 02:50:22PM -0400, Zhanna Tsitkova wrote:
> I would like to summarize the comments made on the list to proceed to  
> the next version of the proposal.
> 
> 1. One should avoid  heavy-lifting in krb5 contexts as they may be  
> frequently created and short-living;
> 2. It is undesirable to do load all plugins up-front, during the start- 
> up. The approach per-need is preferred in many cases.
> 3. The type-safety of plugin interfaces is important. However it comes  
> with the price of making code less readable and, perhaps, negatively  
> effects the performance.

I think the "however" clause on (3) needs more details.  I believe
strong type safety can mostly be obtained by doing things like:

typedef struct <plugin type name>_handle *<plugin type name>_handle_t;
typedef <function pointer> <fname>_fct; /* "_fct" == "function pointer typedef */
...
void *get_plugin_func(
	krb5_context context,
	krb5_plugin_type_t plug_type,
	const char *plugin_name,
	const char *fname);
...
#define	STRINGIFY(x) #s
#define	GET_PLUGIN_FUNC(context, plug_type, plug_name, fname, fct_var, handle_var) \
		({ \
			fname ## _fct v;
			v = (fname ## _fct)get_plugin_func(context, \
			    STRINGIFY(plug_type), plug_name, STRINGIFY(fname)); \
			(handle_var) = (plug_type ## handle_t) \
			    get_plugin_handle(context, \
			    STRINGIFY(plug_type), plug_name); \
			(fct_var) = v;
		})

Then where you need a point a plugin function you'd do something like:

	<plugin type name>_handle_t plug_h;
	<fname>_fct plug_func;

	if (GET_PLUGIN_FUNC(context, some_plug_type, "some_plug_name",
	    some_plug_func, &plug_func, &plug_h) == NULL) {
		/* oops, no such plugin/function */
		...
	}

Look ma'!  Strong type safety!  The macro makes it happen by combining
the ## and # operators to derive suitable type names (defined elsewhere)
and strings that correspond to each other.

The key is clever macro design.

Oh, I know, we're about to get into C standards and GCC features and
portability.  But note that we don't _need_ statement expressions,
whereas we do need the C pre-processor ## and # operators for this to
work.

> As Russ said "a major goal of the plugin architecture should be to try  
> to make the code internals more transparent and obvious.  One of the  
> things that I struggle with right now in the MIT Kerberos code base is  
> that it can be extremely difficult to trace through code and figure  
> out where things are actually being done." It is hard to disagree with  
> this statement. Simplicity is good. But, unfortunately, some degree of  
> the complexity is also unavoidable. And my philosophy here is that we  
> should move as much of this complexity into the plugin management  
> mechanism so that the plugin writers and consumers would enjoy the  
> simplicity and transparency of their tasks.

I don't entirely agree with you on this, though I agree with Russ.  I
believe we're talking about four types of source: a) plugin framework
consumers, b) APIs layered above a plugin framework, c) a plugin
framework, d) the plugins themselves.  As I see it the arguments here
are really about what (b) and (c) look like.  I believe that (c) needs
to be at most a collection of utility types, functions and macros that
(b) uses.

Nico
-- 



More information about the krbdev mailing list