aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore/xenstored_watch.c
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-10-09 23:53:03 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-10-09 23:53:03 +0100
commit5fec4cf7660cbcd50a016750b5de37394c6a65b1 (patch)
treedaaf58a55dd3d55eb08c45c34f77fa10a6fd24c8 /tools/xenstore/xenstored_watch.c
parent25517fd2f2a26162a466a0933cb56c49373fbae7 (diff)
downloadxen-5fec4cf7660cbcd50a016750b5de37394c6a65b1.tar.gz
xen-5fec4cf7660cbcd50a016750b5de37394c6a65b1.tar.bz2
xen-5fec4cf7660cbcd50a016750b5de37394c6a65b1.zip
Simplify reply logic in xenstored. Maintain a linked list
of pending replies that are sent out in order. Currently we only read new requests when the reply list is empty. In fact there is no good reason for this restriction. Another interesting point is that (on my test machine) hotplug blk setup fails if xenstored_client connects to xenstored via the unix domain socket rather than through the kernel --- this points to some user/kernel races that are 'fixed' by the extra serialisation of the in-kernel mutexes. It definitely needs looking into. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'tools/xenstore/xenstored_watch.c')
-rw-r--r--tools/xenstore/xenstored_watch.c87
1 files changed, 21 insertions, 66 deletions
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index dfb0cd1a3e..6f3c2e4e03 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -32,17 +32,6 @@
#include "xenstored_test.h"
#include "xenstored_domain.h"
-/* FIXME: time out unacked watches. */
-struct watch_event
-{
- /* The events on this watch. */
- struct list_head list;
-
- /* Data to send (node\0token\0). */
- unsigned int len;
- char *data;
-};
-
struct watch
{
/* Watches on this connection */
@@ -58,50 +47,17 @@ struct watch
char *node;
};
-/* Look through our watches: if any of them have an event, queue it. */
-void queue_next_event(struct connection *conn)
-{
- struct watch_event *event;
- struct watch *watch;
-
- /* We had a reply queued already? Send it: other end will
- * discard watch. */
- if (conn->waiting_reply) {
- conn->out = conn->waiting_reply;
- conn->waiting_reply = NULL;
- return;
- }
-
- list_for_each_entry(watch, &conn->watches, list) {
- event = list_top(&watch->events, struct watch_event, list);
- if (event) {
- list_del(&event->list);
- talloc_free(event);
- send_reply(conn,XS_WATCH_EVENT,event->data,event->len);
- break;
- }
- }
-}
-
-static int destroy_watch_event(void *_event)
-{
- struct watch_event *event = _event;
-
- trace_destroy(event, "watch_event");
- return 0;
-}
-
static void add_event(struct connection *conn,
struct watch *watch,
const char *name)
{
- struct watch_event *event;
+ /* Data to send (node\0token\0). */
+ unsigned int len;
+ char *data;
if (!check_event_node(name)) {
/* Can this conn load node, or see that it doesn't exist? */
- struct node *node;
-
- node = get_node(conn, name, XS_PERM_READ);
+ struct node *node = get_node(conn, name, XS_PERM_READ);
if (!node && errno != ENOENT)
return;
}
@@ -112,14 +68,12 @@ static void add_event(struct connection *conn,
name++;
}
- event = talloc(watch, struct watch_event);
- event->len = strlen(name) + 1 + strlen(watch->token) + 1;
- event->data = talloc_array(event, char, event->len);
- strcpy(event->data, name);
- strcpy(event->data + strlen(name) + 1, watch->token);
- talloc_set_destructor(event, destroy_watch_event);
- list_add_tail(&event->list, &watch->events);
- trace_create(event, "watch_event");
+ len = strlen(name) + 1 + strlen(watch->token) + 1;
+ data = talloc_array(watch, char, len);
+ strcpy(data, name);
+ strcpy(data + strlen(name) + 1, watch->token);
+ send_reply(conn, XS_WATCH_EVENT, data, len);
+ talloc_free(data);
}
/* FIXME: we fail to fire on out of memory. Should drop connections. */
@@ -139,11 +93,6 @@ void fire_watches(struct connection *conn, const char *name, bool recurse)
add_event(i, watch, name);
else if (recurse && is_child(watch->node, name))
add_event(i, watch, watch->node);
- else
- continue;
- /* If connection not doing anything, queue this. */
- if (i->state == OK)
- queue_next_event(i);
}
}
}
@@ -231,13 +180,19 @@ void do_unwatch(struct connection *conn, struct buffered_data *in)
void dump_watches(struct connection *conn)
{
struct watch *watch;
- struct watch_event *event;
- list_for_each_entry(watch, &conn->watches, list) {
+ list_for_each_entry(watch, &conn->watches, list)
printf(" watch on %s token %s\n",
watch->node, watch->token);
- list_for_each_entry(event, &watch->events, list)
- printf(" event: %s\n", event->data);
- }
}
#endif
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */