[Libguestfs] [PATCH nbdkit v2 1/3] plugins: Move locking to a new file.

Richard W.M. Jones
Tue, 16 Jan 2018 16:32:36 -0000

Mostly code motion.
---
 src/Makefile.am   |   1 +
 src/connections.c |  14 +++----
 src/internal.h    |  14 ++++---
 src/locks.c       | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/plugins.c     |  77 +++++-------------------------------
 5 files changed, 142 insertions(+), 79 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 12b9043..1f05eab 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -40,6 +40,7 @@ nbdkit_SOURCES = \
 	crypto.c \
 	errors.c \
 	internal.h \
+	locks.c \
 	main.c \
 	plugins.c \
 	protocol.h \
diff --git a/src/connections.c b/src/connections.c
index 111a810..74bb8e4 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -211,7 +211,7 @@ _handle_single_connection (int sockin, int sockout)
   int nworkers = threads ? threads : DEFAULT_PARALLEL_REQUESTS;
   pthread_t *workers = NULL;

-  if (!plugin_is_parallel() || nworkers == 1)
+  if (plugin_thread_model () < NBDKIT_THREAD_MODEL_PARALLEL || nworkers ==
1)
     nworkers = 0;
   conn = new_connection (sockin, sockout, nworkers);
   if (!conn)
@@ -287,9 +287,9 @@ handle_single_connection (int sockin, int sockout)
 {
   int r;

-  plugin_lock_connection ();
+  lock_connection ();
   r = _handle_single_connection (sockin, sockout);
-  plugin_unlock_connection ();
+  unlock_connection ();

   return r;
 }
@@ -740,12 +740,12 @@ negotiate_handshake (struct connection *conn)
 {
   int r;

-  plugin_lock_request (conn);
+  lock_request (conn);
   if (!newstyle)
     r = _negotiate_handshake_oldstyle (conn);
   else
     r = _negotiate_handshake_newstyle (conn);
-  plugin_unlock_request (conn);
+  unlock_request (conn);

   return r;
 }
@@ -1057,9 +1057,9 @@ recv_request_send_reply (struct connection *conn)
     error = ESHUTDOWN;
   }
   else {
-    plugin_lock_request (conn);
+    lock_request (conn);
     error = handle_request (conn, cmd, flags, offset, count, buf);
-    plugin_unlock_request (conn);
+    unlock_request (conn);
   }

   /* Send the reply packet. */
diff --git a/src/internal.h b/src/internal.h
index 73bc09e..068204b 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -144,17 +144,13 @@ extern int crypto_negotiate_tls (struct connection *conn,
int sockin, int sockou
 /* plugins.c */
 extern void plugin_register (const char *_filename, void *_dl, struct
nbdkit_plugin *(*plugin_init) (void));
 extern void plugin_cleanup (void);
+extern int plugin_thread_model (void);
 extern const char *plugin_name (void);
 extern void plugin_usage (void);
 extern const char *plugin_version (void);
 extern void plugin_dump_fields (void);
 extern void plugin_config (const char *key, const char *value);
 extern void plugin_config_complete (void);
-extern void plugin_lock_connection (void);
-extern void plugin_unlock_connection (void);
-extern void plugin_lock_request (struct connection *conn);
-extern void plugin_unlock_request (struct connection *conn);
-extern bool plugin_is_parallel (void);
 extern int plugin_errno_is_preserved (void);
 extern int plugin_open (struct connection *conn, int readonly);
 extern void plugin_close (struct connection *conn);
@@ -169,6 +165,14 @@ extern int plugin_flush (struct connection *conn);
 extern int plugin_trim (struct connection *conn, uint32_t count, uint64_t
offset);
 extern int plugin_zero (struct connection *conn, uint32_t count, uint64_t
offset, int may_trim);

+/* locks.c */
+extern void lock_connection (void);
+extern void unlock_connection (void);
+extern void lock_request (struct connection *conn);
+extern void unlock_request (struct connection *conn);
+extern void lock_unload (void);
+extern void unlock_unload (void);
+
 /* sockets.c */
 extern int *bind_unix_socket (size_t *);
 extern int *bind_tcpip_socket (size_t *);
diff --git a/src/locks.c b/src/locks.c
new file mode 100644
index 0000000..6021356
--- /dev/null
+++ b/src/locks.c
@@ -0,0 +1,115 @@
+/* nbdkit
+ * Copyright (C) 2013-2018 Red Hat Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Red Hat nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS
IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "internal.h"
+
+static pthread_mutex_t connection_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t all_requests_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_rwlock_t unload_prevention_lock = PTHREAD_RWLOCK_INITIALIZER;
+
+void
+lock_connection (void)
+{
+  int thread_model = plugin_thread_model ();
+
+  if (thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS) {
+    debug ("acquire connection lock");
+    pthread_mutex_lock (&connection_lock);
+  }
+}
+
+void
+unlock_connection (void)
+{
+  int thread_model = plugin_thread_model ();
+
+  if (thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS) {
+    debug ("release connection lock");
+    pthread_mutex_unlock (&connection_lock);
+  }
+}
+
+void
+lock_request (struct connection *conn)
+{
+  int thread_model = plugin_thread_model ();
+
+  if (thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS) {
+    debug ("acquire global request lock");
+    pthread_mutex_lock (&all_requests_lock);
+  }
+
+  if (thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS) {
+    debug ("acquire per-connection request lock");
+    pthread_mutex_lock (connection_get_request_lock (conn));
+  }
+
+  debug ("acquire unload prevention lock");
+  pthread_rwlock_rdlock (&unload_prevention_lock);
+}
+
+void
+unlock_request (struct connection *conn)
+{
+  int thread_model = plugin_thread_model ();
+
+  debug ("release unload prevention lock");
+  pthread_rwlock_unlock (&unload_prevention_lock);
+
+  if (thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS) {
+    debug ("release per-connection request lock");
+    pthread_mutex_unlock (connection_get_request_lock (conn));
+  }
+
+  if (thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS) {
+    debug ("release global request lock");
+    pthread_mutex_unlock (&all_requests_lock);
+  }
+}
+
+void
+lock_unload (void)
+{
+  pthread_rwlock_wrlock (&unload_prevention_lock);
+}
+
+void
+unlock_unload (void)
+{
+  pthread_rwlock_unlock (&unload_prevention_lock);
+}
diff --git a/src/plugins.c b/src/plugins.c
index 9b5d2d5..b7ab43d 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -46,10 +46,6 @@
 #include "nbdkit-plugin.h"
 #include "internal.h"

-static pthread_mutex_t connection_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t all_requests_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_rwlock_t unload_prevention_lock = PTHREAD_RWLOCK_INITIALIZER;
-
 /* Maximum read or write request that we will handle. */
 #define MAX_REQUEST_SIZE (64 * 1024 * 1024)

@@ -165,7 +161,7 @@ plugin_cleanup (void)
     /* Acquiring this lock prevents any plugin callbacks from running
      * simultaneously.
      */
-    pthread_rwlock_wrlock (&unload_prevention_lock);
+    lock_unload ();

     debug ("%s: unload", filename);
     if (plugin.unload)
@@ -176,10 +172,18 @@ plugin_cleanup (void)
     free (filename);
     filename = NULL;

-    pthread_rwlock_unlock (&unload_prevention_lock);
+    unlock_unload ();
   }
 }

+int
+plugin_thread_model (void)
+{
+  assert (dl);
+
+  return plugin._thread_model;
+}
+
 const char *
 plugin_name (void)
 {
@@ -312,67 +316,6 @@ plugin_config_complete (void)
     exit (EXIT_FAILURE);
 }

-/* Handle the thread model. */
-void
-plugin_lock_connection (void)
-{
-  if (plugin._thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS) {
-    debug ("%s: acquire connection lock", filename);
-    pthread_mutex_lock (&connection_lock);
-  }
-}
-
-void
-plugin_unlock_connection (void)
-{
-  if (plugin._thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS) {
-    debug ("%s: release connection lock", filename);
-    pthread_mutex_unlock (&connection_lock);
-  }
-}
-
-void
-plugin_lock_request (struct connection *conn)
-{
-  if (plugin._thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS) {
-    debug ("acquire global request lock");
-    pthread_mutex_lock (&all_requests_lock);
-  }
-
-  if (plugin._thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS) {
-    debug ("acquire per-connection request lock");
-    pthread_mutex_lock (connection_get_request_lock (conn));
-  }
-
-  debug ("acquire unload prevention lock");
-  pthread_rwlock_rdlock (&unload_prevention_lock);
-}
-
-void
-plugin_unlock_request (struct connection *conn)
-{
-  debug ("release unload prevention lock");
-  pthread_rwlock_unlock (&unload_prevention_lock);
-
-  if (plugin._thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS) {
-    debug ("release per-connection request lock");
-    pthread_mutex_unlock (connection_get_request_lock (conn));
-  }
-
-  if (plugin._thread_model <= NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS) {
-    debug ("release global request lock");
-    pthread_mutex_unlock (&all_requests_lock);
-  }
-}
-
-bool
-plugin_is_parallel (void)
-{
-  assert (dl);
-
-  return plugin._thread_model >= NBDKIT_THREAD_MODEL_PARALLEL;
-}
-
 int
 plugin_errno_is_preserved (void)
 {
--
2.13.2