These methods are called just before and just after the data serving
phase respectively. They are unused in this commit, but make more
sense when used from filters.
---
src/connections.c | 37 +++++++++++++++++++++++++++++++++++++
src/internal.h | 2 ++
src/plugins.c | 18 ++++++++++++++++++
3 files changed, 57 insertions(+)
diff --git a/src/connections.c b/src/connections.c
index e225b5c..be19996 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -93,6 +93,8 @@ static struct connection *new_connection (int sockin, int sockout,
static void free_connection (struct connection *conn);
static int negotiate_handshake (struct connection *conn);
static int recv_request_send_reply (struct connection *conn);
+static int prepare (struct connection *conn);
+static int finalize (struct connection *conn);
/* Don't call these raw socket functions directly. Use conn->recv etc. */
static int raw_recv (struct connection *, void *buf, size_t len);
@@ -250,6 +252,10 @@ _handle_single_connection (int sockin, int sockout)
if (negotiate_handshake (conn) == -1)
goto done;
+ /* Prepare for data serving phase. */
+ if (prepare (conn) == -1)
+ goto done;
+
if (!nworkers) {
/* No need for a separate thread. */
debug ("handshake complete, processing requests serially");
@@ -300,6 +306,10 @@ _handle_single_connection (int sockin, int sockout)
free (workers);
}
+ /* Finalize connection after data serving phase. */
+ if (finalize (conn) == -1)
+ goto done;
+
r = get_status (conn);
done:
debug ("connection cleanup with final status %d", r);
@@ -775,6 +785,33 @@ negotiate_handshake (struct connection *conn)
return r;
}
+static int
+prepare (struct connection *conn)
+{
+ int r;
+
+ lock_request (conn);
+ r = backend->prepare (backend, conn);
+ unlock_request (conn);
+
+ return r;
+}
+
+static int
+finalize (struct connection *conn)
+{
+ int r;
+
+ lock_request (conn);
+ if (backend)
+ r = backend->finalize (backend, conn);
+ else
+ r = 0;
+ unlock_request (conn);
+
+ return r;
+}
+
static bool
valid_range (struct connection *conn, uint64_t offset, uint32_t count)
{
diff --git a/src/internal.h b/src/internal.h
index 8047b3b..dbcd89c 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -165,6 +165,8 @@ struct backend {
void (*config_complete) (struct backend *);
int (*errno_is_preserved) (struct backend *);
int (*open) (struct backend *, struct connection *conn, int readonly);
+ int (*prepare) (struct backend *, struct connection *conn);
+ int (*finalize) (struct backend *, struct connection *conn);
void (*close) (struct backend *, struct connection *conn);
int64_t (*get_size) (struct backend *, struct connection *conn);
int (*can_write) (struct backend *, struct connection *conn);
diff --git a/src/plugins.c b/src/plugins.c
index 137bae3..da11c2c 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -251,6 +251,22 @@ plugin_open (struct backend *b, struct connection *conn, int
readonly)
return 0;
}
+/* We don't expose .prepare and .finalize to plugins since they aren't
+ * necessary. Plugins can easily do the same work in .open and
+ * .close.
+ */
+static int
+plugin_prepare (struct backend *b, struct connection *conn)
+{
+ return 0;
+}
+
+static int
+plugin_finalize (struct backend *b, struct connection *conn)
+{
+ return 0;
+}
+
static void
plugin_close (struct backend *b, struct connection *conn)
{
@@ -503,6 +519,8 @@ static struct backend plugin_functions = {
.config_complete = plugin_config_complete,
.errno_is_preserved = plugin_errno_is_preserved,
.open = plugin_open,
+ .prepare = plugin_prepare,
+ .finalize = plugin_finalize,
.close = plugin_close,
.get_size = plugin_get_size,
.can_write = plugin_can_write,
--
2.15.1