diff options
author | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-07-26 15:09:43 +0000 |
---|---|---|
committer | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-07-26 15:09:43 +0000 |
commit | e08ecc0000058e476a61af2b503ce34580bd63bc (patch) | |
tree | 47c2f9f90c4b2231ad30b100beae2bd2ca18d473 /tools/xenstore/xenstored_watch.c | |
parent | a9c1da21e112a3b0672594fd9c247214a67af10b (diff) | |
download | xen-e08ecc0000058e476a61af2b503ce34580bd63bc.tar.gz xen-e08ecc0000058e476a61af2b503ce34580bd63bc.tar.bz2 xen-e08ecc0000058e476a61af2b503ce34580bd63bc.zip |
Test and fix acknowedge_watch from returning EINVAL.
Also ensure that daemon re-xmits event if they ack wrong thing
(otherwise confused clients get stuck, as we will send no more
data while awaiting ack).
Signed-off-by: Rusty Russel <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Diffstat (limited to 'tools/xenstore/xenstored_watch.c')
-rw-r--r-- | tools/xenstore/xenstored_watch.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index 6945dd91e0..70bfbaa595 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -102,7 +102,7 @@ void queue_next_event(struct connection *conn) if (conn->waiting_reply) { conn->out = conn->waiting_reply; conn->waiting_reply = NULL; - conn->waiting_for_ack = false; + conn->waiting_for_ack = NULL; return; } @@ -115,7 +115,7 @@ void queue_next_event(struct connection *conn) return; /* If we decide to cancel, we will reset this. */ - conn->waiting_for_ack = true; + conn->waiting_for_ack = event->watches[0]; /* If we deleted /foo and they're watching /foo/bar, that's what we * tell them has changed. */ @@ -348,12 +348,17 @@ bool do_watch_ack(struct connection *conn, const char *token) if (!conn->waiting_for_ack) return send_error(conn, ENOENT); - event = get_first_event(conn); - if (!streq(event->watches[0]->token, token)) + event = list_top(&conn->waiting_for_ack->events, + struct watch_event, list); + assert(event->watches[0] == conn->waiting_for_ack); + if (!streq(conn->waiting_for_ack->token, token)) { + /* They're confused: this will cause us to send event again */ + conn->waiting_for_ack = NULL; return send_error(conn, EINVAL); + } move_event_onwards(event); - conn->waiting_for_ack = false; + conn->waiting_for_ack = NULL; return send_ack(conn, XS_WATCH_ACK); } |