aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl
diff options
context:
space:
mode:
authorIan Jackson <ian.jackson@eu.citrix.com>2011-12-12 17:48:41 +0000
committerIan Jackson <ian.jackson@eu.citrix.com>2011-12-12 17:48:41 +0000
commit51d3b77be07f5f2057581ab2c5d65f6631996154 (patch)
tree7876334923fdc5c6bd3428dcc1ae2082c318742a /tools/libxl
parent8618d4e458b1202af92ba9aad026cb201f0d58bd (diff)
downloadxen-51d3b77be07f5f2057581ab2c5d65f6631996154.tar.gz
xen-51d3b77be07f5f2057581ab2c5d65f6631996154.tar.bz2
xen-51d3b77be07f5f2057581ab2c5d65f6631996154.zip
libxl: introduce lock in libxl_ctx
This lock will be used to protect data structures which will be hung off the libxl_ctx in subsequent patches. Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> Committed-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxl')
-rw-r--r--tools/libxl/libxl.c6
-rw-r--r--tools/libxl/libxl_internal.h27
2 files changed, 33 insertions, 0 deletions
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index e5cadb2c0a..7a973d0831 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -41,6 +41,7 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version,
{
libxl_ctx *ctx;
struct stat stat_buf;
+ const pthread_mutex_t mutex_value = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
if (version != LIBXL_VERSION)
return ERROR_VERSION;
@@ -54,6 +55,11 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version,
memset(ctx, 0, sizeof(libxl_ctx));
ctx->lg = lg;
+ /* This somewhat convoluted approach is needed because
+ * PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP is defined to be valid
+ * only as an initialiser, not as an expression. */
+ memcpy(&ctx->lock, &mutex_value, sizeof(ctx->lock));
+
if ( stat(XENSTORE_PID_FILE, &stat_buf) != 0 ) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Is xenstore daemon running?\n"
"failed to stat %s", XENSTORE_PID_FILE);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index e66b86a081..0fedcd9bd6 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
+#include <pthread.h>
#include <xs.h>
#include <xenctrl.h>
@@ -95,6 +96,18 @@ struct libxl__ctx {
xc_interface *xch;
struct xs_handle *xsh;
+ pthread_mutex_t lock; /* protects data structures hanging off the ctx */
+ /* Always use CTX_LOCK and CTX_UNLOCK to manipulate this.
+ *
+ * You may acquire this mutex recursively if it is convenient to
+ * do so. You may not acquire this lock at the same time as any
+ * other lock. If you need to call application code outside
+ * libxl (ie, a callback) with this lock held then it is
+ * necessaray to impose restrictions on the caller to maintain a
+ * proper lock hierarchy, and these restrictions must then be
+ * documented in the libxl public interface.
+ */
+
/* for callers who reap children willy-nilly; caller must only
* set this after libxl_init and before any other call - or
* may leave them untouched */
@@ -669,6 +682,20 @@ libxl__device_model_version_running(libxl__gc *gc, uint32_t domid);
#define CTX libxl__gc_owner(gc)
+/* Locking functions. See comment for "lock" member of libxl__ctx. */
+
+#define CTX_LOCK do { \
+ int mutex_r = pthread_mutex_lock(&CTX->lock); \
+ assert(!mutex_r); \
+ } while(0)
+
+#define CTX_UNLOCK do { \
+ int mutex_r = pthread_mutex_unlock(&CTX->lock); \
+ assert(!mutex_r); \
+ } while(0)
+
+
+
/*
* Inserts "elm_new" into the sorted list "head".
*