No need for filters to specify their model in two different ways; the
callback alone is sufficient. Since all filters are in-tree, we can
deal with the API/ABI change made here.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
docs/nbdkit-filter.pod | 48 +++++++++++++++------------------
include/nbdkit-filter.h | 6 ++---
filters/cow/cow.c | 2 --
filters/delay/delay.c | 2 --
filters/error/error.c | 2 --
filters/fua/fua.c | 2 --
filters/log/log.c | 2 --
filters/nocache/nocache.c | 2 --
filters/noextents/noextents.c | 2 --
filters/noparallel/noparallel.c | 2 --
filters/nozero/nozero.c | 2 --
filters/offset/offset.c | 2 --
filters/partition/partition.c | 2 --
filters/rate/rate.c | 2 --
filters/readahead/readahead.c | 2 --
filters/stats/stats.c | 2 --
filters/truncate/truncate.c | 2 --
filters/xz/xz.c | 6 ++++-
server/filters.c | 10 +++----
19 files changed, 32 insertions(+), 68 deletions(-)
diff --git a/docs/nbdkit-filter.pod b/docs/nbdkit-filter.pod
index 4033789..86894f1 100644
--- a/docs/nbdkit-filter.pod
+++ b/docs/nbdkit-filter.pod
@@ -6,8 +6,6 @@ nbdkit-filter - how to write nbdkit filters
#include <nbdkit-filter.h>
- #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static int
myfilter_config (nbdkit_next_config *next, void *nxdata,
const char *key, const char *value)
@@ -107,24 +105,6 @@ should not expect to distribute filters separately from nbdkit.
All filters should start by including this header file.
-=head1 C<#define THREAD_MODEL>
-
-All filters must define a default thread model by defining
-C<THREAD_MODEL>. See L<nbdkit-plugin(3)/THREADS> for a discussion of
-thread models.
-
-The final thread model is the smallest (ie. most serialized) out of
-all the filters and the plugin. Filters cannot alter the thread model
-to make it larger (more parallel). However, they can dynamically
-request a smaller (more serialized) model from decisions made during
-C<.config> and C<.config_complete>, by implementing a <.thread_model>
-function callback.
-
-If possible filters should be be written to handle fully parallel
-requests (C<NBDKIT_THREAD_MODEL_PARALLEL>, even multiple requests
-issued in parallel on the same connection). This ensures that they
-don't slow down other filters or plugins.
-
=head1 C<struct nbdkit_filter>
All filters must define and register one C<struct nbdkit_filter>,
@@ -275,13 +255,27 @@ omit this.
int (*thread_model) (void);
-This optional function is called after C<.config_complete> to provide
-the filter an opportunity to reduce the resulting thread model below
-the value used at compilation via C<THREAD_MODEL>. The resulting
-thread model for all connections is determined by selecting the most
-restrictive model from the C<THREAD_MODEL> of the plugin and all
-filters, and from the results of any C<.thread_model> across all
-filters.
+=head1 C<#define THREAD_MODEL>
+
+Filters may tighten (but not relax) the thread model of the plugin, by
+defining this callback. Note that while plugins use a compile-time
+definition of C<THREAD_MODEL>, filters do not need to declare a model
+at compile time; instead, this callback is called after
+C<.config_complete> and before any connections are created. See
+L<nbdkit-plugin(3)/THREADS> for a discussion of thread models.
+
+The final thread model used by nbdkit is the smallest (ie. most
+serialized) out of all the filters and the plugin, and applies for all
+connections. Requests for a model larger than permitted by the plugin
+are silently ignored. It is acceptable for decisions made during
+C<.config> and C<.config_complete> to determine which model to
+request.
+
+This callback is optional; if it is not present, the filter must be
+written to handle fully parallel requests, even if it is multiple
+requests issued in parallel on the same connection, similar to a
+plugin requesting C<NBDKIT_THREAD_MODEL_PARALLEL>. This ensures the
+filter doesn't slow down other filters or plugins.
If there is an error, C<.thread_model> should call C<nbdkit_error>
with an error message and return C<-1>.
diff --git a/include/nbdkit-filter.h b/include/nbdkit-filter.h
index 70d32ce..94f1778 100644
--- a/include/nbdkit-filter.h
+++ b/include/nbdkit-filter.h
@@ -93,13 +93,12 @@ struct nbdkit_next_ops {
};
struct nbdkit_filter {
- /* Do not set these fields directly; use NBDKIT_REGISTER_FILTER.
- * They exist so that we can diagnose filters compiled against
+ /* Do not set this field directly; use NBDKIT_REGISTER_FILTER.
+ * It exists so that we can diagnose filters compiled against
* one version of the header with a runtime compiled against a
* different version.
*/
int _api_version;
- int _thread_model;
/* Because there is no ABI guarantee, new fields may be added
* where logically appropriate. */
@@ -178,7 +177,6 @@ struct nbdkit_filter {
filter_init (void) \
{ \
(filter)._api_version = NBDKIT_FILTER_API_VERSION; \
- (filter)._thread_model = THREAD_MODEL; \
return &(filter); \
}
diff --git a/filters/cow/cow.c b/filters/cow/cow.c
index 006007e..ae4a3af 100644
--- a/filters/cow/cow.c
+++ b/filters/cow/cow.c
@@ -51,8 +51,6 @@
#include "minmax.h"
#include "rounding.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
/* In order to handle parallel requests safely, this lock must be held
* when calling any blk_* functions.
*/
diff --git a/filters/delay/delay.c b/filters/delay/delay.c
index 486a24e..11681c8 100644
--- a/filters/delay/delay.c
+++ b/filters/delay/delay.c
@@ -40,8 +40,6 @@
#include <nbdkit-filter.h>
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static int delay_read_ms = 0; /* read delay (milliseconds) */
static int delay_write_ms = 0; /* write delay (milliseconds) */
static int delay_zero_ms = 0; /* zero delay (milliseconds) */
diff --git a/filters/error/error.c b/filters/error/error.c
index aba6213..968f283 100644
--- a/filters/error/error.c
+++ b/filters/error/error.c
@@ -48,8 +48,6 @@
#include "cleanup.h"
#include "random.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
struct error_settings {
int error; /* errno, eg. EIO */
double rate; /* rate, 0.0 = never, 1.0 = always */
diff --git a/filters/fua/fua.c b/filters/fua/fua.c
index 120ff0a..9d0e561 100644
--- a/filters/fua/fua.c
+++ b/filters/fua/fua.c
@@ -41,8 +41,6 @@
#include <nbdkit-filter.h>
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static enum FuaMode {
NONE,
EMULATE,
diff --git a/filters/log/log.c b/filters/log/log.c
index 133e352..9c0f35c 100644
--- a/filters/log/log.c
+++ b/filters/log/log.c
@@ -47,8 +47,6 @@
#include "cleanup.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static uint64_t connections;
static char *logfilename;
static FILE *logfile;
diff --git a/filters/nocache/nocache.c b/filters/nocache/nocache.c
index abb042e..a3f1198 100644
--- a/filters/nocache/nocache.c
+++ b/filters/nocache/nocache.c
@@ -43,8 +43,6 @@
#include "minmax.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static enum CacheMode {
NONE,
EMULATE,
diff --git a/filters/noextents/noextents.c b/filters/noextents/noextents.c
index 59f4c37..e39723c 100644
--- a/filters/noextents/noextents.c
+++ b/filters/noextents/noextents.c
@@ -34,8 +34,6 @@
#include <nbdkit-filter.h>
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static int
noextents_can_extents (struct nbdkit_next_ops *next_ops, void *nxdata,
void *handle)
diff --git a/filters/noparallel/noparallel.c b/filters/noparallel/noparallel.c
index 7034b01..057485f 100644
--- a/filters/noparallel/noparallel.c
+++ b/filters/noparallel/noparallel.c
@@ -41,8 +41,6 @@
#include <nbdkit-filter.h>
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static int thread_model = NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS;
static int
diff --git a/filters/nozero/nozero.c b/filters/nozero/nozero.c
index 6e0ffa9..16ec710 100644
--- a/filters/nozero/nozero.c
+++ b/filters/nozero/nozero.c
@@ -43,8 +43,6 @@
#include "minmax.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
#define MAX_WRITE (64 * 1024 * 1024)
static const char buffer[MAX_WRITE];
diff --git a/filters/offset/offset.c b/filters/offset/offset.c
index fe07d28..efe5c6d 100644
--- a/filters/offset/offset.c
+++ b/filters/offset/offset.c
@@ -41,8 +41,6 @@
#include "cleanup.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static int64_t offset = 0, range = -1;
/* Called for each key=value passed on the command line. */
diff --git a/filters/partition/partition.c b/filters/partition/partition.c
index ee2cc77..56ad05e 100644
--- a/filters/partition/partition.c
+++ b/filters/partition/partition.c
@@ -45,8 +45,6 @@
#include "partition.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
int partnum = -1;
/* Called for each key=value passed on the command line. */
diff --git a/filters/rate/rate.c b/filters/rate/rate.c
index cf03541..30e093e 100644
--- a/filters/rate/rate.c
+++ b/filters/rate/rate.c
@@ -50,8 +50,6 @@
#include "bucket.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
/* Per-connection and global limit, both in bits per second, with zero
* meaning not set / not enforced. These are only used when reading
* the command line and initializing the buckets for the first time.
diff --git a/filters/readahead/readahead.c b/filters/readahead/readahead.c
index 95bda0e..b6c1809 100644
--- a/filters/readahead/readahead.c
+++ b/filters/readahead/readahead.c
@@ -45,8 +45,6 @@
#include "cleanup.h"
#include "minmax.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
/* Copied from server/plugins.c. */
#define MAX_REQUEST_SIZE (64 * 1024 * 1024)
diff --git a/filters/stats/stats.c b/filters/stats/stats.c
index 037fc61..4f94f73 100644
--- a/filters/stats/stats.c
+++ b/filters/stats/stats.c
@@ -47,8 +47,6 @@
#include "cleanup.h"
#include "tvdiff.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
static char *filename;
static bool append;
static FILE *fp;
diff --git a/filters/truncate/truncate.c b/filters/truncate/truncate.c
index 38b1cd9..64be839 100644
--- a/filters/truncate/truncate.c
+++ b/filters/truncate/truncate.c
@@ -46,8 +46,6 @@
#include "iszero.h"
#include "rounding.h"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
/* These are the parameters. */
static int64_t truncate_size = -1;
static unsigned round_up = 0, round_down = 0;
diff --git a/filters/xz/xz.c b/filters/xz/xz.c
index 8ada294..51ac919 100644
--- a/filters/xz/xz.c
+++ b/filters/xz/xz.c
@@ -246,7 +246,10 @@ xz_pread (struct nbdkit_next_ops *next_ops, void *nxdata,
return 0;
}
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS
+static int xz_thread_model (void)
+{
+ return NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS;
+}
static struct nbdkit_filter filter = {
.name = "xz",
@@ -254,6 +257,7 @@ static struct nbdkit_filter filter = {
.version = PACKAGE_VERSION,
.config = xz_config,
.config_help = xz_config_help,
+ .thread_model = xz_thread_model,
.open = xz_open,
.close = xz_close,
.prepare = xz_prepare,
diff --git a/server/filters.c b/server/filters.c
index 87a9c0e..3d9e1ef 100644
--- a/server/filters.c
+++ b/server/filters.c
@@ -93,20 +93,18 @@ static int
filter_thread_model (struct backend *b)
{
struct backend_filter *f = container_of (b, struct backend_filter, backend);
- int filter_thread_model = f->filter._thread_model;
+ int filter_thread_model = NBDKIT_THREAD_MODEL_PARALLEL;
int thread_model = f->backend.next->thread_model (f->backend.next);
- if (filter_thread_model < thread_model) /* more serialized */
- thread_model = filter_thread_model;
-
if (f->filter.thread_model) {
filter_thread_model = f->filter.thread_model ();
if (filter_thread_model == -1)
exit (EXIT_FAILURE);
- if (filter_thread_model < thread_model)
- thread_model = filter_thread_model;
}
+ if (filter_thread_model < thread_model) /* more serialized */
+ thread_model = filter_thread_model;
+
return thread_model;
}
--
2.20.1