Plugins cannot get rid of #define THREAD_MODEL (doing so would break API/ABI compatibility); however, we CAN add an optional callback for allowing a runtime reduction of the thread model. This can be especially useful for language bindings, as in the next patch, where the C glue code for the language has to cater to the maximum parallelism possible for that language, but where an individual plugin may still want to be stricter.
Signed-off-by: Eric Blake <[email protected]> --- docs/nbdkit-plugin.pod | 33 +++++++++++++++++++++++++++++---- include/nbdkit-plugin.h | 2 ++ server/plugins.c | 12 +++++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod index 7f83234..9a20663 100644 --- a/docs/nbdkit-plugin.pod +++ b/docs/nbdkit-plugin.pod @@ -133,6 +133,12 @@ has been passed to the plugin. Both are called after loading the plugin but before any connections are accepted. +=item C<.thread_model> + +C<.thread_model> is called once after all configuration information +has been passed to the plugin, and before any connections are +accepted. + =item C<.open> A new client has connected. @@ -466,6 +472,19 @@ what already appears in C<.description>. If the plugin doesn't take any config parameters you should probably omit this. +=head2 C<.thread_model> + + int thread_model (void) + +This optional callback is called after all the configuration has been +passed to the plugin. It can be used to force a stricter thread model +based on configuration, compared to C<THREAD_MODEL>. See L</THREADS> +below for details. Attempts to request a looser (more parallel) model +are silently ignored. + +If there is an error, C<.thread_model> should call C<nbdkit_error> +with an error message and return C<-1>. + =head2 C<.open> void *open (int readonly); @@ -898,9 +917,14 @@ error message, and C<nbdkit_set_error> to record an appropriate error =head1 THREADS -Each nbdkit plugin must declare its thread safety model by defining -the C<THREAD_MODEL> macro. (This macro is used by -C<NBDKIT_REGISTER_PLUGIN>). +Each nbdkit plugin must declare its maximum thread safety model by +defining the C<THREAD_MODEL> macro. (This macro is used by +C<NBDKIT_REGISTER_PLUGIN>). Additionally, a plugin may implement the +C<.thread_model> callback, called right after C<.config_complete> to +make a runtime decision on which thread model to use. The nbdkit +server chooses the most restrictive model between the plugin's +C<THREAD_MODEL>, the C<.thread_model> if present, and any restrictions +requested by filters. The possible settings for C<THREAD_MODEL> are defined below. @@ -935,7 +959,8 @@ parallel. However only one request will happen per handle at a time =item C<#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL> Multiple handles can be open and multiple data requests can happen in -parallel (even on the same handle). +parallel (even on the same handle). The server may reorder replies, +answering a later request before an earlier one. All the libraries you use must be thread-safe and reentrant. You may also need to provide mutexes for fields in your connection handle. diff --git a/include/nbdkit-plugin.h b/include/nbdkit-plugin.h index e9b1808..632df86 100644 --- a/include/nbdkit-plugin.h +++ b/include/nbdkit-plugin.h @@ -130,6 +130,8 @@ struct nbdkit_plugin { struct nbdkit_extents *extents); int (*can_cache) (void *handle); int (*cache) (void *handle, uint32_t count, uint64_t offset, uint32_t flags); + + int (*thread_model) (void); }; extern void nbdkit_set_error (int err); diff --git a/server/plugins.c b/server/plugins.c index f293e6a..85736bb 100644 --- a/server/plugins.c +++ b/server/plugins.c @@ -87,8 +87,18 @@ static int plugin_thread_model (struct backend *b) { struct backend_plugin *p = container_of (b, struct backend_plugin, backend); + int thread_model = p->plugin._thread_model; + int r; - return p->plugin._thread_model; + if (p->plugin.thread_model) { + r = p->plugin.thread_model (); + if (r == -1) + exit (EXIT_FAILURE); + if (r < thread_model) + thread_model = r; + } + + return thread_model; } static const char * -- 2.20.1 _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
