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