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 <eblake(a)redhat.com>
---
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