char_device: Add spice_char_device_write_buffer_get_server_no_token()

To allow the server to send agent messages without needing to wait for a
self-token. IE for sending VD_AGENT_CLIENT_DISCONNECTED messages.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Hans de Goede 2013-03-06 12:51:43 +01:00
parent e67e47fb33
commit 4476c99452
2 changed files with 29 additions and 15 deletions

View File

@ -72,6 +72,7 @@ enum {
WRITE_BUFFER_ORIGIN_NONE,
WRITE_BUFFER_ORIGIN_CLIENT,
WRITE_BUFFER_ORIGIN_SERVER,
WRITE_BUFFER_ORIGIN_SERVER_NO_TOKEN,
};
/* Holding references for avoiding access violation if the char device was
@ -488,15 +489,14 @@ static void spice_char_dev_write_retry(void *opaque)
spice_char_device_write_to_device(dev);
}
static SpiceCharDeviceWriteBuffer *__spice_char_device_write_buffer_get(SpiceCharDeviceState *dev,
RedClient *client,
int size,
int migrated_data_tokens)
static SpiceCharDeviceWriteBuffer *__spice_char_device_write_buffer_get(
SpiceCharDeviceState *dev, RedClient *client,
int size, int origin, int migrated_data_tokens)
{
RingItem *item;
SpiceCharDeviceWriteBuffer *ret;
if (!client && !dev->num_self_tokens) {
if (origin == WRITE_BUFFER_ORIGIN_SERVER && !dev->num_self_tokens) {
return NULL;
}
@ -513,8 +513,10 @@ static SpiceCharDeviceWriteBuffer *__spice_char_device_write_buffer_get(SpiceCha
ret->buf = spice_realloc(ret->buf, size);
ret->buf_size = size;
}
ret->origin = origin;
if (client) {
if (origin == WRITE_BUFFER_ORIGIN_CLIENT) {
spice_assert(client);
SpiceCharDeviceClientState *dev_client = spice_char_device_client_find(dev, client);
if (dev_client) {
if (!migrated_data_tokens &&
@ -523,7 +525,6 @@ static SpiceCharDeviceWriteBuffer *__spice_char_device_write_buffer_get(SpiceCha
spice_char_device_handle_client_overflow(dev_client);
goto error;
}
ret->origin = WRITE_BUFFER_ORIGIN_CLIENT;
ret->client = client;
if (!migrated_data_tokens && dev_client->do_flow_control) {
dev_client->num_client_tokens--;
@ -534,8 +535,7 @@ static SpiceCharDeviceWriteBuffer *__spice_char_device_write_buffer_get(SpiceCha
spice_printerr("client not found: dev %p client %p", dev, client);
goto error;
}
} else {
ret->origin = WRITE_BUFFER_ORIGIN_SERVER;
} else if (origin == WRITE_BUFFER_ORIGIN_SERVER) {
dev->num_self_tokens--;
}
@ -551,7 +551,16 @@ SpiceCharDeviceWriteBuffer *spice_char_device_write_buffer_get(SpiceCharDeviceSt
RedClient *client,
int size)
{
return __spice_char_device_write_buffer_get(dev, client, size, 0);
return __spice_char_device_write_buffer_get(dev, client, size,
client ? WRITE_BUFFER_ORIGIN_CLIENT : WRITE_BUFFER_ORIGIN_SERVER,
0);
}
SpiceCharDeviceWriteBuffer *spice_char_device_write_buffer_get_server_no_token(
SpiceCharDeviceState *dev, int size)
{
return __spice_char_device_write_buffer_get(dev, NULL, size,
WRITE_BUFFER_ORIGIN_SERVER_NO_TOKEN, 0);
}
static SpiceCharDeviceWriteBuffer *spice_char_device_write_buffer_ref(SpiceCharDeviceWriteBuffer *write_buf)
@ -945,12 +954,14 @@ int spice_char_device_state_restore(SpiceCharDeviceState *dev,
if (mig_data->write_size > 0) {
if (mig_data->write_num_client_tokens) {
dev->cur_write_buf = __spice_char_device_write_buffer_get(dev, client_state->client,
mig_data->write_size,
mig_data->write_num_client_tokens);
dev->cur_write_buf =
__spice_char_device_write_buffer_get(dev, client_state->client,
mig_data->write_size, WRITE_BUFFER_ORIGIN_CLIENT,
mig_data->write_num_client_tokens);
} else {
dev->cur_write_buf = __spice_char_device_write_buffer_get(dev, NULL, mig_data->write_size,
0);
dev->cur_write_buf =
__spice_char_device_write_buffer_get(dev, NULL,
mig_data->write_size, WRITE_BUFFER_ORIGIN_SERVER, 0);
}
/* the first write buffer contains all the data that was saved for migration */
memcpy(dev->cur_write_buf->buf,

View File

@ -181,6 +181,9 @@ void spice_char_device_send_to_client_tokens_set(SpiceCharDeviceState *dev,
SpiceCharDeviceWriteBuffer *spice_char_device_write_buffer_get(SpiceCharDeviceState *dev,
RedClient *client, int size);
SpiceCharDeviceWriteBuffer *spice_char_device_write_buffer_get_server_no_token(
SpiceCharDeviceState *dev, int size);
/* Either add the buffer to the write queue or release it */
void spice_char_device_write_buffer_add(SpiceCharDeviceState *dev,
SpiceCharDeviceWriteBuffer *write_buf);