aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore/xs.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/xenstore/xs.c')
-rw-r--r--tools/xenstore/xs.c100
1 files changed, 69 insertions, 31 deletions
diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c
index dbbf8ef394..94db1ce45e 100644
--- a/tools/xenstore/xs.c
+++ b/tools/xenstore/xs.c
@@ -32,7 +32,6 @@
#include <signal.h>
#include <stdint.h>
#include <errno.h>
-#include <pthread.h>
#include "xs.h"
#include "list.h"
#include "utils.h"
@@ -43,6 +42,10 @@ struct xs_stored_msg {
char *body;
};
+#ifdef USE_PTHREAD
+
+#include <pthread.h>
+
struct xs_handle {
/* Communications channel to xenstore daemon. */
int fd;
@@ -78,14 +81,37 @@ struct xs_handle {
pthread_mutex_t request_mutex;
};
-static int read_message(struct xs_handle *h);
+#define mutex_lock(m) pthread_mutex_lock(m)
+#define mutex_unlock(m) pthread_mutex_unlock(m)
+#define condvar_signal(c) pthread_cond_signal(c)
+#define condvar_wait(c,m,hnd) pthread_cond_wait(c,m)
+
static void *read_thread(void *arg);
+#else /* !defined(USE_PTHREAD) */
+
+struct xs_handle {
+ int fd;
+ struct list_head reply_list;
+ struct list_head watch_list;
+ /* Clients can select() on this pipe to wait for a watch to fire. */
+ int watch_pipe[2];
+};
+
+#define mutex_lock(m) ((void)0)
+#define mutex_unlock(m) ((void)0)
+#define condvar_signal(c) ((void)0)
+#define condvar_wait(c,m,hnd) read_message(hnd)
+
+#endif
+
+static int read_message(struct xs_handle *h);
+
int xs_fileno(struct xs_handle *h)
{
char c = 0;
- pthread_mutex_lock(&h->watch_mutex);
+ mutex_lock(&h->watch_mutex);
if ((h->watch_pipe[0] == -1) && (pipe(h->watch_pipe) != -1)) {
/* Kick things off if the watch list is already non-empty. */
@@ -94,7 +120,7 @@ int xs_fileno(struct xs_handle *h)
continue;
}
- pthread_mutex_unlock(&h->watch_mutex);
+ mutex_unlock(&h->watch_mutex);
return h->watch_pipe[0];
}
@@ -163,18 +189,21 @@ static struct xs_handle *get_handle(const char *connect_to)
h->fd = fd;
+ INIT_LIST_HEAD(&h->reply_list);
+ INIT_LIST_HEAD(&h->watch_list);
+
/* Watch pipe is allocated on demand in xs_fileno(). */
h->watch_pipe[0] = h->watch_pipe[1] = -1;
- INIT_LIST_HEAD(&h->watch_list);
+#ifdef USE_PTHREAD
pthread_mutex_init(&h->watch_mutex, NULL);
pthread_cond_init(&h->watch_condvar, NULL);
- INIT_LIST_HEAD(&h->reply_list);
pthread_mutex_init(&h->reply_mutex, NULL);
pthread_cond_init(&h->reply_condvar, NULL);
pthread_mutex_init(&h->request_mutex, NULL);
+#endif
return h;
}
@@ -198,15 +227,17 @@ void xs_daemon_close(struct xs_handle *h)
{
struct xs_stored_msg *msg, *tmsg;
- pthread_mutex_lock(&h->request_mutex);
- pthread_mutex_lock(&h->reply_mutex);
- pthread_mutex_lock(&h->watch_mutex);
+ mutex_lock(&h->request_mutex);
+ mutex_lock(&h->reply_mutex);
+ mutex_lock(&h->watch_mutex);
+#ifdef USE_PTHREAD
if (h->read_thr_exists) {
/* XXX FIXME: May leak an unpublished message buffer. */
pthread_cancel(h->read_thr);
pthread_join(h->read_thr, NULL);
}
+#endif
list_for_each_entry_safe(msg, tmsg, &h->reply_list, list) {
free(msg->body);
@@ -218,9 +249,9 @@ void xs_daemon_close(struct xs_handle *h)
free(msg);
}
- pthread_mutex_unlock(&h->request_mutex);
- pthread_mutex_unlock(&h->reply_mutex);
- pthread_mutex_unlock(&h->watch_mutex);
+ mutex_unlock(&h->request_mutex);
+ mutex_unlock(&h->reply_mutex);
+ mutex_unlock(&h->watch_mutex);
if (h->watch_pipe[0] != -1) {
close(h->watch_pipe[0]);
@@ -277,17 +308,19 @@ static void *read_reply(
struct xs_stored_msg *msg;
char *body;
+#ifdef USE_PTHREAD
/* Read from comms channel ourselves if there is no reader thread. */
if (!h->read_thr_exists && (read_message(h) == -1))
return NULL;
+#endif
- pthread_mutex_lock(&h->reply_mutex);
+ mutex_lock(&h->reply_mutex);
while (list_empty(&h->reply_list))
- pthread_cond_wait(&h->reply_condvar, &h->reply_mutex);
+ condvar_wait(&h->reply_condvar, &h->reply_mutex, h);
msg = list_top(&h->reply_list, struct xs_stored_msg, list);
list_del(&msg->list);
assert(list_empty(&h->reply_list));
- pthread_mutex_unlock(&h->reply_mutex);
+ mutex_unlock(&h->reply_mutex);
*type = msg->hdr.type;
if (len)
@@ -329,7 +362,7 @@ static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
ignorepipe.sa_flags = 0;
sigaction(SIGPIPE, &ignorepipe, &oldact);
- pthread_mutex_lock(&h->request_mutex);
+ mutex_lock(&h->request_mutex);
if (!xs_write_all(h->fd, &msg, sizeof(msg)))
goto fail;
@@ -342,7 +375,7 @@ static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
if (!ret)
goto fail;
- pthread_mutex_unlock(&h->request_mutex);
+ mutex_unlock(&h->request_mutex);
sigaction(SIGPIPE, &oldact, NULL);
if (msg.type == XS_ERROR) {
@@ -362,7 +395,7 @@ static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
fail:
/* We're in a bad state, so close fd. */
saved_errno = errno;
- pthread_mutex_unlock(&h->request_mutex);
+ mutex_unlock(&h->request_mutex);
sigaction(SIGPIPE, &oldact, NULL);
close_fd:
close(h->fd);
@@ -556,16 +589,18 @@ bool xs_watch(struct xs_handle *h, const char *path, const char *token)
{
struct iovec iov[2];
+#ifdef USE_PTHREAD
/* We dynamically create a reader thread on demand. */
- pthread_mutex_lock(&h->request_mutex);
+ mutex_lock(&h->request_mutex);
if (!h->read_thr_exists) {
if (pthread_create(&h->read_thr, NULL, read_thread, h) != 0) {
- pthread_mutex_unlock(&h->request_mutex);
+ mutex_unlock(&h->request_mutex);
return false;
}
h->read_thr_exists = 1;
}
- pthread_mutex_unlock(&h->request_mutex);
+ mutex_unlock(&h->request_mutex);
+#endif
iov[0].iov_base = (void *)path;
iov[0].iov_len = strlen(path) + 1;
@@ -586,11 +621,11 @@ char **xs_read_watch(struct xs_handle *h, unsigned int *num)
char **ret, *strings, c = 0;
unsigned int num_strings, i;
- pthread_mutex_lock(&h->watch_mutex);
+ mutex_lock(&h->watch_mutex);
/* Wait on the condition variable for a watch to fire. */
while (list_empty(&h->watch_list))
- pthread_cond_wait(&h->watch_condvar, &h->watch_mutex);
+ condvar_wait(&h->watch_condvar, &h->watch_mutex, h);
msg = list_top(&h->watch_list, struct xs_stored_msg, list);
list_del(&msg->list);
@@ -599,7 +634,7 @@ char **xs_read_watch(struct xs_handle *h, unsigned int *num)
while (read(h->watch_pipe[0], &c, 1) != 1)
continue;
- pthread_mutex_unlock(&h->watch_mutex);
+ mutex_unlock(&h->watch_mutex);
assert(msg->hdr.type == XS_WATCH_EVENT);
@@ -801,7 +836,7 @@ static int read_message(struct xs_handle *h)
body[msg->hdr.len] = '\0';
if (msg->hdr.type == XS_WATCH_EVENT) {
- pthread_mutex_lock(&h->watch_mutex);
+ mutex_lock(&h->watch_mutex);
/* Kick users out of their select() loop. */
if (list_empty(&h->watch_list) &&
@@ -810,22 +845,23 @@ static int read_message(struct xs_handle *h)
continue;
list_add_tail(&msg->list, &h->watch_list);
- pthread_cond_signal(&h->watch_condvar);
- pthread_mutex_unlock(&h->watch_mutex);
+ condvar_signal(&h->watch_condvar);
+
+ mutex_unlock(&h->watch_mutex);
} else {
- pthread_mutex_lock(&h->reply_mutex);
+ mutex_lock(&h->reply_mutex);
/* There should only ever be one response pending! */
if (!list_empty(&h->reply_list)) {
- pthread_mutex_unlock(&h->reply_mutex);
+ mutex_unlock(&h->reply_mutex);
goto error;
}
list_add_tail(&msg->list, &h->reply_list);
- pthread_cond_signal(&h->reply_condvar);
+ condvar_signal(&h->reply_condvar);
- pthread_mutex_unlock(&h->reply_mutex);
+ mutex_unlock(&h->reply_mutex);
}
return 0;
@@ -838,6 +874,7 @@ static int read_message(struct xs_handle *h)
return -1;
}
+#ifdef USE_PTHREAD
static void *read_thread(void *arg)
{
struct xs_handle *h = arg;
@@ -847,6 +884,7 @@ static void *read_thread(void *arg)
return NULL;
}
+#endif
/*
* Local variables: