diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2012-08-02 22:55:53 +0300 |
---|---|---|
committer | Yonit Halperin <yhalperi@redhat.com> | 2012-08-27 09:13:02 +0300 |
commit | cb767a83fda2b93b47de284719353b3d073120be (patch) | |
tree | 9c65e48564607ac96ba0253f718f613156f67f27 /server/char_device.c | |
parent | b0264a5e37b308c8a5b268974aa9936014a9389f (diff) | |
download | spice-cb767a83fda2b93b47de284719353b3d073120be.tar.gz spice-cb767a83fda2b93b47de284719353b3d073120be.tar.xz spice-cb767a83fda2b93b47de284719353b3d073120be.zip |
char device migration: don't read or write from/to the device while waiting for migraion data
Diffstat (limited to 'server/char_device.c')
-rw-r--r-- | server/char_device.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/server/char_device.c b/server/char_device.c index 84121e6d..d97c6dda 100644 --- a/server/char_device.c +++ b/server/char_device.c @@ -45,6 +45,8 @@ struct SpiceCharDeviceClientState { struct SpiceCharDeviceState { int running; + int active; /* has read/write been performed since the device was started */ + int wait_for_migrate_data; uint32_t refs; Ring write_queue; @@ -268,7 +270,7 @@ static int spice_char_device_read_from_device(SpiceCharDeviceState *dev) uint64_t max_send_tokens; int did_read = FALSE; - if (!dev->running) { + if (!dev->running || dev->wait_for_migrate_data) { return FALSE; } @@ -307,6 +309,7 @@ static int spice_char_device_read_from_device(SpiceCharDeviceState *dev) } dev->during_read_from_device = 0; spice_char_device_state_unref(dev); + dev->active = dev->active || did_read; return did_read; } @@ -415,7 +418,7 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev) int total = 0; int n; - if (!dev->running) { + if (!dev->running || dev->wait_for_migrate_data) { return 0; } @@ -462,6 +465,7 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev) spice_assert(ring_is_empty(&dev->write_queue)); } spice_char_device_state_unref(dev); + dev->active = dev->active || total; return total; } @@ -682,13 +686,17 @@ void spice_char_device_client_add(SpiceCharDeviceState *dev, int do_flow_control, uint32_t max_send_queue_size, uint32_t num_client_tokens, - uint32_t num_send_tokens) + uint32_t num_send_tokens, + int wait_for_migrate_data) { SpiceCharDeviceClientState *dev_client; spice_assert(dev); spice_assert(client); + spice_assert(!wait_for_migrate_data || (dev->num_clients == 0 && !dev->active)); + dev->wait_for_migrate_data = wait_for_migrate_data; + spice_debug("dev_state %p client %p", dev, client); dev_client = spice_new0(SpiceCharDeviceClientState, 1); dev_client->dev = dev; @@ -727,8 +735,12 @@ void spice_char_device_client_remove(SpiceCharDeviceState *dev, spice_error("client wasn't found"); return; } - spice_char_device_client_free(dev, dev_client); + if (dev->wait_for_migrate_data) { + spice_assert(dev->num_clients == 0); + dev->wait_for_migrate_data = FALSE; + spice_char_device_read_from_device(dev); + } } int spice_char_device_client_exists(SpiceCharDeviceState *dev, @@ -751,14 +763,16 @@ void spice_char_device_stop(SpiceCharDeviceState *dev) { spice_debug("dev_state %p", dev); dev->running = FALSE; + dev->active = FALSE; core->timer_cancel(dev->write_to_dev_timer); } void spice_char_device_reset(SpiceCharDeviceState *dev) { RingItem *client_item; - spice_char_device_stop(dev); + spice_char_device_stop(dev); + dev->wait_for_migrate_data = FALSE; spice_debug("dev_state %p", dev); while (!ring_is_empty(&dev->write_queue)) { RingItem *item = ring_get_tail(&dev->write_queue); |