diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-06-03 11:09:14 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-06-03 11:09:14 +0100 |
commit | 8323478d5bd96cb1c00cd67da33f59a42965d9be (patch) | |
tree | 3d710fd5ec5b81c3e10d65a0c7208224dd23ae55 /extras/mini-os/xenbus/xenbus.c | |
parent | 44d374adc01fc7cd3e516d6475dc5e9ddedf928d (diff) | |
download | xen-8323478d5bd96cb1c00cd67da33f59a42965d9be.tar.gz xen-8323478d5bd96cb1c00cd67da33f59a42965d9be.tar.bz2 xen-8323478d5bd96cb1c00cd67da33f59a42965d9be.zip |
minios: refactor xenbus state machine
Implement xenbus_wait_for_state_change and xenbus_switch_state and
change the various frontends to use the two functions and do proper
error checking.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/xenbus/xenbus.c')
-rw-r--r-- | extras/mini-os/xenbus/xenbus.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/extras/mini-os/xenbus/xenbus.c b/extras/mini-os/xenbus/xenbus.c index 5ed42a3da7..958e010dab 100644 --- a/extras/mini-os/xenbus/xenbus.c +++ b/extras/mini-os/xenbus/xenbus.c @@ -120,6 +120,70 @@ char* xenbus_wait_for_value(const char* path, const char* value, xenbus_event_qu return NULL; } +char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, XenbusState state) +{ + char *current_state; + char *msg = NULL; + char *msg2 = NULL; + char value[2]; + XenbusState rs; + int xbt_flag = 0; + int retry = 0; + + do { + if (xbt == XBT_NIL) { + xenbus_transaction_start(&xbt); + xbt_flag = 1; + } + + msg = xenbus_read(xbt, path, ¤t_state); + if (msg) goto exit; + + rs = (XenbusState) (current_state[0] - '0'); + free(current_state); + if (rs == state) { + msg = NULL; + goto exit; + } + + snprintf(value, 2, "%d", state); + msg = xenbus_write(xbt, path, value); + +exit: + if (xbt_flag) + msg2 = xenbus_transaction_end(xbt, 0, &retry); + if (msg == NULL && msg2 != NULL) + msg = msg2; + } while (retry); + + return msg; +} + +char *xenbus_wait_for_state_change(const char* path, XenbusState *state, xenbus_event_queue *queue) +{ + if (!queue) + queue = &xenbus_events; + for(;;) + { + char *res, *msg; + XenbusState rs; + + msg = xenbus_read(XBT_NIL, path, &res); + if(msg) return msg; + + rs = (XenbusState) (res[0] - 48); + free(res); + + if (rs == *state) + xenbus_wait_for_watch(queue); + else { + *state = rs; + break; + } + } + return NULL; +} + static void xenbus_thread_func(void *ign) { |