mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-04 00:06:29 +00:00
char-device: Automatically convert functions to methods
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
parent
5f7aaf2a9a
commit
1411383483
@ -382,18 +382,16 @@ red_char_device_send_to_client_tokens_absorb(RedCharDevice *dev,
|
||||
}
|
||||
}
|
||||
|
||||
void red_char_device_send_to_client_tokens_add(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client,
|
||||
uint32_t tokens)
|
||||
void RedCharDevice::send_to_client_tokens_add(RedCharDeviceClientOpaque *client,
|
||||
uint32_t tokens)
|
||||
{
|
||||
red_char_device_send_to_client_tokens_absorb(dev, client, tokens, false);
|
||||
red_char_device_send_to_client_tokens_absorb(this, client, tokens, false);
|
||||
}
|
||||
|
||||
void red_char_device_send_to_client_tokens_set(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client,
|
||||
uint32_t tokens)
|
||||
void RedCharDevice::send_to_client_tokens_set(RedCharDeviceClientOpaque *client,
|
||||
uint32_t tokens)
|
||||
{
|
||||
red_char_device_send_to_client_tokens_absorb(dev, client, tokens, true);
|
||||
red_char_device_send_to_client_tokens_absorb(this, client, tokens, true);
|
||||
}
|
||||
|
||||
/**************************
|
||||
@ -466,7 +464,8 @@ static int red_char_device_write_to_device(RedCharDevice *dev)
|
||||
total += n;
|
||||
write_len -= n;
|
||||
if (!write_len) {
|
||||
red_char_device_write_buffer_release(dev, &dev->priv->cur_write_buf);
|
||||
RedCharDevice::write_buffer_release(dev,
|
||||
&dev->priv->cur_write_buf);
|
||||
continue;
|
||||
}
|
||||
dev->priv->cur_write_buf_pos += n;
|
||||
@ -554,21 +553,19 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RedCharDeviceWriteBuffer *red_char_device_write_buffer_get_client(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client,
|
||||
int size)
|
||||
RedCharDeviceWriteBuffer *RedCharDevice::write_buffer_get_client(RedCharDeviceClientOpaque *client,
|
||||
int size)
|
||||
{
|
||||
spice_assert(client);
|
||||
return red_char_device_write_buffer_get(dev, client, size, WRITE_BUFFER_ORIGIN_CLIENT, 0);
|
||||
return red_char_device_write_buffer_get(this, client, size, WRITE_BUFFER_ORIGIN_CLIENT, 0);
|
||||
}
|
||||
|
||||
RedCharDeviceWriteBuffer *red_char_device_write_buffer_get_server(RedCharDevice *dev,
|
||||
int size,
|
||||
bool use_token)
|
||||
RedCharDeviceWriteBuffer *RedCharDevice::write_buffer_get_server(int size,
|
||||
bool use_token)
|
||||
{
|
||||
WriteBufferOrigin origin =
|
||||
use_token ? WRITE_BUFFER_ORIGIN_SERVER : WRITE_BUFFER_ORIGIN_SERVER_NO_TOKEN;
|
||||
return red_char_device_write_buffer_get(dev, NULL, size, origin, 0);
|
||||
return red_char_device_write_buffer_get(this, NULL, size, origin, 0);
|
||||
}
|
||||
|
||||
static RedCharDeviceWriteBuffer *red_char_device_write_buffer_ref(RedCharDeviceWriteBuffer *write_buf)
|
||||
@ -588,24 +585,23 @@ static void red_char_device_write_buffer_unref(RedCharDeviceWriteBuffer *write_b
|
||||
red_char_device_write_buffer_free(write_buf);
|
||||
}
|
||||
|
||||
void red_char_device_write_buffer_add(RedCharDevice *dev,
|
||||
RedCharDeviceWriteBuffer *write_buf)
|
||||
void RedCharDevice::write_buffer_add(RedCharDeviceWriteBuffer *write_buf)
|
||||
{
|
||||
spice_assert(dev);
|
||||
|
||||
/* caller shouldn't add buffers for client that was removed */
|
||||
if (write_buf->priv->origin == WRITE_BUFFER_ORIGIN_CLIENT &&
|
||||
!red_char_device_client_find(dev, write_buf->priv->client)) {
|
||||
g_warning("client not found: dev %p client %p", dev, write_buf->priv->client);
|
||||
!red_char_device_client_find(this, write_buf->priv->client)) {
|
||||
g_warning("client not found: this %p client %p", this, write_buf->priv->client);
|
||||
red_char_device_write_buffer_unref(write_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
g_queue_push_head(&dev->priv->write_queue, write_buf);
|
||||
red_char_device_write_to_device(dev);
|
||||
g_queue_push_head(&priv->write_queue, write_buf);
|
||||
red_char_device_write_to_device(this);
|
||||
}
|
||||
|
||||
void red_char_device_write_buffer_release(RedCharDevice *dev,
|
||||
RedCharDeviceWriteBuffer **p_write_buf)
|
||||
void RedCharDevice::write_buffer_release(RedCharDevice *dev,
|
||||
RedCharDeviceWriteBuffer **p_write_buf)
|
||||
{
|
||||
RedCharDeviceWriteBuffer *write_buf = *p_write_buf;
|
||||
if (!write_buf) {
|
||||
@ -644,15 +640,14 @@ void red_char_device_write_buffer_release(RedCharDevice *dev,
|
||||
* char_device_state management *
|
||||
********************************/
|
||||
|
||||
void red_char_device_reset_dev_instance(RedCharDevice *dev,
|
||||
SpiceCharDeviceInstance *sin)
|
||||
void RedCharDevice::reset_dev_instance(SpiceCharDeviceInstance *sin)
|
||||
{
|
||||
spice_debug("sin %p, char device %p", sin, dev);
|
||||
dev->priv->sin = sin;
|
||||
spice_debug("sin %p, char device %p", sin, this);
|
||||
priv->sin = sin;
|
||||
if (sin)
|
||||
sin->st = dev;
|
||||
if (dev->priv->reds) {
|
||||
red_char_device_init_device_instance(dev);
|
||||
sin->st = this;
|
||||
if (priv->reds) {
|
||||
red_char_device_init_device_instance(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -688,100 +683,97 @@ red_char_device_client_new(RedsState *reds,
|
||||
return dev_client;
|
||||
}
|
||||
|
||||
bool red_char_device_client_add(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client,
|
||||
int do_flow_control,
|
||||
uint32_t max_send_queue_size,
|
||||
uint32_t num_client_tokens,
|
||||
uint32_t num_send_tokens,
|
||||
int wait_for_migrate_data)
|
||||
bool RedCharDevice::client_add(RedCharDeviceClientOpaque *client,
|
||||
int do_flow_control,
|
||||
uint32_t max_send_queue_size,
|
||||
uint32_t num_client_tokens,
|
||||
uint32_t num_send_tokens,
|
||||
int wait_for_migrate_data)
|
||||
{
|
||||
RedCharDeviceClient *dev_client;
|
||||
|
||||
spice_assert(dev);
|
||||
|
||||
spice_assert(client);
|
||||
|
||||
if (wait_for_migrate_data && (dev->priv->clients != NULL || dev->priv->active)) {
|
||||
if (wait_for_migrate_data && (priv->clients != NULL || priv->active)) {
|
||||
spice_warning("can't restore device %p from migration data. The device "
|
||||
"has already been active", dev);
|
||||
"has already been active", this);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dev->priv->wait_for_migrate_data = wait_for_migrate_data;
|
||||
priv->wait_for_migrate_data = wait_for_migrate_data;
|
||||
|
||||
spice_debug("char device %p, client %p", dev, client);
|
||||
dev_client = red_char_device_client_new(dev->priv->reds,
|
||||
spice_debug("char device %p, client %p", this, client);
|
||||
dev_client = red_char_device_client_new(priv->reds,
|
||||
client,
|
||||
do_flow_control,
|
||||
max_send_queue_size,
|
||||
num_client_tokens,
|
||||
num_send_tokens);
|
||||
dev_client->dev = dev;
|
||||
dev->priv->clients = g_list_prepend(dev->priv->clients, dev_client);
|
||||
dev_client->dev = this;
|
||||
priv->clients = g_list_prepend(priv->clients, dev_client);
|
||||
/* Now that we have a client, forward any pending device data */
|
||||
red_char_device_wakeup(dev);
|
||||
wakeup();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void red_char_device_client_remove(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client)
|
||||
void RedCharDevice::client_remove(RedCharDeviceClientOpaque *client)
|
||||
{
|
||||
RedCharDeviceClient *dev_client;
|
||||
|
||||
spice_debug("char device %p, client %p", dev, client);
|
||||
dev_client = red_char_device_client_find(dev, client);
|
||||
spice_debug("char device %p, client %p", this, client);
|
||||
dev_client = red_char_device_client_find(this, client);
|
||||
|
||||
if (!dev_client) {
|
||||
spice_error("client wasn't found");
|
||||
return;
|
||||
}
|
||||
red_char_device_client_free(dev, dev_client);
|
||||
if (dev->priv->wait_for_migrate_data) {
|
||||
spice_assert(dev->priv->clients == NULL);
|
||||
dev->priv->wait_for_migrate_data = FALSE;
|
||||
red_char_device_read_from_device(dev);
|
||||
red_char_device_client_free(this, dev_client);
|
||||
if (priv->wait_for_migrate_data) {
|
||||
spice_assert(priv->clients == NULL);
|
||||
priv->wait_for_migrate_data = FALSE;
|
||||
red_char_device_read_from_device(this);
|
||||
}
|
||||
}
|
||||
|
||||
int red_char_device_client_exists(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client)
|
||||
int RedCharDevice::client_exists(RedCharDeviceClientOpaque *client)
|
||||
{
|
||||
return (red_char_device_client_find(dev, client) != NULL);
|
||||
return (red_char_device_client_find(this, client) != NULL);
|
||||
}
|
||||
|
||||
void red_char_device_start(RedCharDevice *dev)
|
||||
void RedCharDevice::start()
|
||||
{
|
||||
spice_debug("char device %p", dev);
|
||||
dev->priv->running = TRUE;
|
||||
dev->ref();
|
||||
while (red_char_device_write_to_device(dev) ||
|
||||
red_char_device_read_from_device(dev));
|
||||
dev->unref();
|
||||
spice_debug("char device %p", this);
|
||||
priv->running = TRUE;
|
||||
ref();
|
||||
while (red_char_device_write_to_device(this) ||
|
||||
red_char_device_read_from_device(this));
|
||||
unref();
|
||||
}
|
||||
|
||||
void red_char_device_stop(RedCharDevice *dev)
|
||||
void RedCharDevice::stop()
|
||||
{
|
||||
spice_debug("char device %p", dev);
|
||||
dev->priv->running = FALSE;
|
||||
dev->priv->active = FALSE;
|
||||
if (dev->priv->write_to_dev_timer) {
|
||||
red_timer_cancel(dev->priv->write_to_dev_timer);
|
||||
spice_debug("char device %p", this);
|
||||
priv->running = FALSE;
|
||||
priv->active = FALSE;
|
||||
if (priv->write_to_dev_timer) {
|
||||
red_timer_cancel(priv->write_to_dev_timer);
|
||||
}
|
||||
}
|
||||
|
||||
void red_char_device_reset(RedCharDevice *dev)
|
||||
void RedCharDevice::reset()
|
||||
{
|
||||
RedCharDeviceClient *dev_client;
|
||||
RedCharDeviceWriteBuffer *buf;
|
||||
|
||||
dev->priv->wait_for_migrate_data = FALSE;
|
||||
spice_debug("char device %p", dev);
|
||||
while ((buf = (RedCharDeviceWriteBuffer *) g_queue_pop_tail(&dev->priv->write_queue))) {
|
||||
red_char_device_write_buffer_release(dev, &buf);
|
||||
priv->wait_for_migrate_data = FALSE;
|
||||
spice_debug("char device %p", this);
|
||||
while ((buf = (RedCharDeviceWriteBuffer *) g_queue_pop_tail(&priv->write_queue))) {
|
||||
RedCharDevice::write_buffer_release(this, &buf);
|
||||
}
|
||||
red_char_device_write_buffer_release(dev, &dev->priv->cur_write_buf);
|
||||
RedCharDevice::write_buffer_release(this, &priv->cur_write_buf);
|
||||
|
||||
GLIST_FOREACH(dev->priv->clients, RedCharDeviceClient, dev_client) {
|
||||
GLIST_FOREACH(priv->clients, RedCharDeviceClient, dev_client) {
|
||||
spice_debug("send_queue_empty %d", g_queue_is_empty(dev_client->send_queue));
|
||||
dev_client->num_send_tokens += g_queue_get_length(dev_client->send_queue);
|
||||
g_queue_free_full(dev_client->send_queue, (GDestroyNotify)red_pipe_item_unref);
|
||||
@ -795,17 +787,17 @@ void red_char_device_reset(RedCharDevice *dev)
|
||||
}
|
||||
}
|
||||
|
||||
void red_char_device_wakeup(RedCharDevice *dev)
|
||||
void RedCharDevice::wakeup()
|
||||
{
|
||||
red_char_device_write_to_device(dev);
|
||||
red_char_device_read_from_device(dev);
|
||||
red_char_device_write_to_device(this);
|
||||
red_char_device_read_from_device(this);
|
||||
}
|
||||
|
||||
/*************
|
||||
* Migration *
|
||||
* **********/
|
||||
|
||||
void red_char_device_migrate_data_marshall_empty(SpiceMarshaller *m)
|
||||
void RedCharDevice::migrate_data_marshall_empty(SpiceMarshaller *m)
|
||||
{
|
||||
SpiceMigrateDataCharDevice *mig_data;
|
||||
|
||||
@ -824,8 +816,7 @@ static void migrate_data_marshaller_write_buffer_free(uint8_t *data, void *opaqu
|
||||
red_char_device_write_buffer_unref(write_buf);
|
||||
}
|
||||
|
||||
void red_char_device_migrate_data_marshall(RedCharDevice *dev,
|
||||
SpiceMarshaller *m)
|
||||
void RedCharDevice::migrate_data_marshall(SpiceMarshaller *m)
|
||||
{
|
||||
RedCharDeviceClient *dev_client;
|
||||
GList *item;
|
||||
@ -835,8 +826,8 @@ void red_char_device_migrate_data_marshall(RedCharDevice *dev,
|
||||
SpiceMarshaller *m2;
|
||||
|
||||
/* multi-clients are not supported */
|
||||
spice_assert(g_list_length(dev->priv->clients) == 1);
|
||||
dev_client = (RedCharDeviceClient *) g_list_last(dev->priv->clients)->data;
|
||||
spice_assert(g_list_length(priv->clients) == 1);
|
||||
dev_client = (RedCharDeviceClient *) g_list_last(priv->clients)->data;
|
||||
/* FIXME: if there were more than one client before the marshalling,
|
||||
* it is possible that the send_queue length > 0, and the send data
|
||||
* should be migrated as well */
|
||||
@ -850,21 +841,21 @@ void red_char_device_migrate_data_marshall(RedCharDevice *dev,
|
||||
write_to_dev_tokens = 0;
|
||||
|
||||
m2 = spice_marshaller_get_ptr_submarshaller(m);
|
||||
if (dev->priv->cur_write_buf) {
|
||||
uint32_t buf_remaining = dev->priv->cur_write_buf->buf + dev->priv->cur_write_buf->buf_used -
|
||||
dev->priv->cur_write_buf_pos;
|
||||
spice_marshaller_add_by_ref_full(m2, dev->priv->cur_write_buf_pos, buf_remaining,
|
||||
if (priv->cur_write_buf) {
|
||||
uint32_t buf_remaining = priv->cur_write_buf->buf + priv->cur_write_buf->buf_used -
|
||||
priv->cur_write_buf_pos;
|
||||
spice_marshaller_add_by_ref_full(m2, priv->cur_write_buf_pos, buf_remaining,
|
||||
migrate_data_marshaller_write_buffer_free,
|
||||
red_char_device_write_buffer_ref(dev->priv->cur_write_buf)
|
||||
red_char_device_write_buffer_ref(priv->cur_write_buf)
|
||||
);
|
||||
write_to_dev_size += buf_remaining;
|
||||
if (dev->priv->cur_write_buf->priv->origin == WRITE_BUFFER_ORIGIN_CLIENT) {
|
||||
spice_assert(dev->priv->cur_write_buf->priv->client == dev_client->client);
|
||||
write_to_dev_tokens += dev->priv->cur_write_buf->priv->token_price;
|
||||
if (priv->cur_write_buf->priv->origin == WRITE_BUFFER_ORIGIN_CLIENT) {
|
||||
spice_assert(priv->cur_write_buf->priv->client == dev_client->client);
|
||||
write_to_dev_tokens += priv->cur_write_buf->priv->token_price;
|
||||
}
|
||||
}
|
||||
|
||||
for (item = g_queue_peek_tail_link(&dev->priv->write_queue); item != NULL; item = item->prev) {
|
||||
for (item = g_queue_peek_tail_link(&priv->write_queue); item != NULL; item = item->prev) {
|
||||
RedCharDeviceWriteBuffer *write_buf = (RedCharDeviceWriteBuffer *) item->data;
|
||||
|
||||
spice_marshaller_add_by_ref_full(m2, write_buf->buf, write_buf->buf_used,
|
||||
@ -878,27 +869,26 @@ void red_char_device_migrate_data_marshall(RedCharDevice *dev,
|
||||
}
|
||||
}
|
||||
spice_debug("migration data dev %p: write_queue size %u tokens %u",
|
||||
dev, write_to_dev_size, write_to_dev_tokens);
|
||||
this, write_to_dev_size, write_to_dev_tokens);
|
||||
spice_marshaller_set_uint32(m, write_to_dev_sizes_ptr, write_to_dev_size);
|
||||
spice_marshaller_set_uint32(m, write_to_dev_sizes_ptr + sizeof(uint32_t), write_to_dev_tokens);
|
||||
}
|
||||
|
||||
bool red_char_device_restore(RedCharDevice *dev,
|
||||
SpiceMigrateDataCharDevice *mig_data)
|
||||
bool RedCharDevice::restore(SpiceMigrateDataCharDevice *mig_data)
|
||||
{
|
||||
RedCharDeviceClient *dev_client;
|
||||
uint32_t client_tokens_window;
|
||||
|
||||
spice_assert(g_list_length(dev->priv->clients) == 1 &&
|
||||
dev->priv->wait_for_migrate_data);
|
||||
spice_assert(g_list_length(priv->clients) == 1 &&
|
||||
priv->wait_for_migrate_data);
|
||||
|
||||
dev_client = (RedCharDeviceClient *) g_list_last(dev->priv->clients)->data;
|
||||
dev_client = (RedCharDeviceClient *) g_list_last(priv->clients)->data;
|
||||
if (mig_data->version > SPICE_MIGRATE_DATA_CHAR_DEVICE_VERSION) {
|
||||
spice_error("dev %p error: migration data version %u is bigger than self %u",
|
||||
dev, mig_data->version, SPICE_MIGRATE_DATA_CHAR_DEVICE_VERSION);
|
||||
this, mig_data->version, SPICE_MIGRATE_DATA_CHAR_DEVICE_VERSION);
|
||||
return FALSE;
|
||||
}
|
||||
spice_assert(!dev->priv->cur_write_buf && g_queue_is_empty(&dev->priv->write_queue));
|
||||
spice_assert(!priv->cur_write_buf && g_queue_is_empty(&priv->write_queue));
|
||||
spice_assert(mig_data->connected);
|
||||
|
||||
client_tokens_window = dev_client->num_client_tokens; /* initial state of tokens */
|
||||
@ -911,31 +901,31 @@ bool red_char_device_restore(RedCharDevice *dev,
|
||||
|
||||
if (mig_data->write_size > 0) {
|
||||
if (mig_data->write_num_client_tokens) {
|
||||
dev->priv->cur_write_buf =
|
||||
red_char_device_write_buffer_get(dev, dev_client->client,
|
||||
priv->cur_write_buf =
|
||||
red_char_device_write_buffer_get(this, dev_client->client,
|
||||
mig_data->write_size, WRITE_BUFFER_ORIGIN_CLIENT,
|
||||
mig_data->write_num_client_tokens);
|
||||
} else {
|
||||
dev->priv->cur_write_buf =
|
||||
red_char_device_write_buffer_get(dev, NULL,
|
||||
priv->cur_write_buf =
|
||||
red_char_device_write_buffer_get(this, 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->priv->cur_write_buf->buf,
|
||||
memcpy(priv->cur_write_buf->buf,
|
||||
((uint8_t *)mig_data) + mig_data->write_data_ptr - sizeof(SpiceMigrateDataHeader),
|
||||
mig_data->write_size);
|
||||
dev->priv->cur_write_buf->buf_used = mig_data->write_size;
|
||||
dev->priv->cur_write_buf_pos = dev->priv->cur_write_buf->buf;
|
||||
priv->cur_write_buf->buf_used = mig_data->write_size;
|
||||
priv->cur_write_buf_pos = priv->cur_write_buf->buf;
|
||||
}
|
||||
dev->priv->wait_for_migrate_data = FALSE;
|
||||
red_char_device_write_to_device(dev);
|
||||
red_char_device_read_from_device(dev);
|
||||
priv->wait_for_migrate_data = FALSE;
|
||||
red_char_device_write_to_device(this);
|
||||
red_char_device_read_from_device(this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SpiceServer* red_char_device_get_server(RedCharDevice *dev)
|
||||
SpiceServer* RedCharDevice::get_server()
|
||||
{
|
||||
return dev->priv->reds;
|
||||
return priv->reds;
|
||||
}
|
||||
|
||||
SpiceCharDeviceInterface *spice_char_device_get_interface(SpiceCharDeviceInstance *instance)
|
||||
@ -1009,7 +999,7 @@ red_char_device_set_property(GObject *object,
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CHAR_DEV_INSTANCE:
|
||||
red_char_device_reset_dev_instance(self, (SpiceCharDeviceInstance*) g_value_get_pointer(value));
|
||||
self->reset_dev_instance((SpiceCharDeviceInstance *)g_value_get_pointer(value));
|
||||
break;
|
||||
case PROP_SPICE_SERVER:
|
||||
self->priv->reds = (SpiceServer *) g_value_get_pointer(value);
|
||||
@ -1115,9 +1105,9 @@ SPICE_GNUC_VISIBLE void spice_server_port_event(SpiceCharDeviceInstance *sin, ui
|
||||
return klass->port_event(sin->st, event);
|
||||
}
|
||||
|
||||
SpiceCharDeviceInstance *red_char_device_get_device_instance(RedCharDevice *dev)
|
||||
SpiceCharDeviceInstance *RedCharDevice::get_device_instance()
|
||||
{
|
||||
return dev->priv->sin;
|
||||
return priv->sin;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -152,79 +152,75 @@ struct RedCharDeviceWriteBuffer {
|
||||
uint8_t buf[0];
|
||||
};
|
||||
|
||||
void red_char_device_reset_dev_instance(RedCharDevice *dev,
|
||||
SpiceCharDeviceInstance *sin);
|
||||
|
||||
/* only one client is supported */
|
||||
void red_char_device_migrate_data_marshall(RedCharDevice *dev,
|
||||
SpiceMarshaller *m);
|
||||
void red_char_device_migrate_data_marshall_empty(SpiceMarshaller *m);
|
||||
|
||||
bool red_char_device_restore(RedCharDevice *dev,
|
||||
SpiceMigrateDataCharDevice *mig_data);
|
||||
|
||||
/*
|
||||
* Resets write/read queues, and moves that state to being stopped.
|
||||
* This routine is a workaround for a bad tokens management in the vdagent
|
||||
* protocol:
|
||||
* The client tokens' are set only once, when the main channel is initialized.
|
||||
* Instead, it would have been more appropriate to reset them upon AGENT_CONNECT.
|
||||
* The client tokens are tracked as part of the RedCharDeviceClient. Thus,
|
||||
* in order to be backward compatible with the client, we need to track the tokens
|
||||
* event when the agent is detached. We don't destroy the char_device state, and
|
||||
* instead we just reset it.
|
||||
* In addition, there is a misshandling of AGENT_TOKENS message in spice-gtk: it
|
||||
* overrides the amount of tokens, instead of adding the given amount.
|
||||
*/
|
||||
void red_char_device_reset(RedCharDevice *dev);
|
||||
|
||||
/* max_send_queue_size = how many messages we can read from the device and enqueue for this client,
|
||||
* when we have tokens for other clients and no tokens for this one */
|
||||
bool red_char_device_client_add(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client,
|
||||
int do_flow_control,
|
||||
uint32_t max_send_queue_size,
|
||||
uint32_t num_client_tokens,
|
||||
uint32_t num_send_tokens,
|
||||
int wait_for_migrate_data);
|
||||
|
||||
void red_char_device_client_remove(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client);
|
||||
int red_char_device_client_exists(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client);
|
||||
|
||||
void red_char_device_start(RedCharDevice *dev);
|
||||
void red_char_device_stop(RedCharDevice *dev);
|
||||
SpiceServer* red_char_device_get_server(RedCharDevice *dev);
|
||||
|
||||
/** Read from device **/
|
||||
|
||||
void red_char_device_wakeup(RedCharDevice *dev);
|
||||
|
||||
void red_char_device_send_to_client_tokens_add(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client,
|
||||
uint32_t tokens);
|
||||
|
||||
|
||||
void red_char_device_send_to_client_tokens_set(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client,
|
||||
uint32_t tokens);
|
||||
/** Write to device **/
|
||||
/* 'SpiceCharDeviceState' name is used for consistency with what spice-char.h exports */
|
||||
struct SpiceCharDeviceState: public GObject
|
||||
{
|
||||
void reset_dev_instance(SpiceCharDeviceInstance *sin);
|
||||
/* only one client is supported */
|
||||
void migrate_data_marshall(SpiceMarshaller *m);
|
||||
static void migrate_data_marshall_empty(SpiceMarshaller *m);
|
||||
|
||||
RedCharDeviceWriteBuffer *red_char_device_write_buffer_get_client(RedCharDevice *dev,
|
||||
RedCharDeviceClientOpaque *client,
|
||||
int size);
|
||||
bool restore(SpiceMigrateDataCharDevice *mig_data);
|
||||
|
||||
/* Returns NULL if use_token == true and no tokens are available */
|
||||
RedCharDeviceWriteBuffer *red_char_device_write_buffer_get_server(RedCharDevice *dev,
|
||||
int size,
|
||||
bool use_token);
|
||||
/*
|
||||
* Resets write/read queues, and moves that state to being stopped.
|
||||
* This routine is a workaround for a bad tokens management in the vdagent
|
||||
* protocol:
|
||||
* The client tokens' are set only once, when the main channel is initialized.
|
||||
* Instead, it would have been more appropriate to reset them upon AGENT_CONNECT.
|
||||
* The client tokens are tracked as part of the RedCharDeviceClient. Thus,
|
||||
* in order to be backward compatible with the client, we need to track the tokens
|
||||
* event when the agent is detached. We don't destroy the char_device state, and
|
||||
* instead we just reset it.
|
||||
* In addition, there is a misshandling of AGENT_TOKENS message in spice-gtk: it
|
||||
* overrides the amount of tokens, instead of adding the given amount.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/* Either add the buffer to the write queue or release it */
|
||||
void red_char_device_write_buffer_add(RedCharDevice *dev,
|
||||
RedCharDeviceWriteBuffer *write_buf);
|
||||
void red_char_device_write_buffer_release(RedCharDevice *dev,
|
||||
RedCharDeviceWriteBuffer **p_write_buf);
|
||||
/* max_send_queue_size = how many messages we can read from the device and enqueue for this client,
|
||||
* when we have tokens for other clients and no tokens for this one */
|
||||
bool client_add(RedCharDeviceClientOpaque *client, int do_flow_control,
|
||||
uint32_t max_send_queue_size, uint32_t num_client_tokens,
|
||||
uint32_t num_send_tokens, int wait_for_migrate_data);
|
||||
|
||||
void client_remove(RedCharDeviceClientOpaque *client);
|
||||
int client_exists(RedCharDeviceClientOpaque *client);
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
SpiceServer* get_server();
|
||||
|
||||
/** Read from device **/
|
||||
|
||||
void wakeup();
|
||||
|
||||
void send_to_client_tokens_add(RedCharDeviceClientOpaque *client,
|
||||
uint32_t tokens);
|
||||
|
||||
|
||||
void send_to_client_tokens_set(RedCharDeviceClientOpaque *client,
|
||||
uint32_t tokens);
|
||||
/** Write to device **/
|
||||
|
||||
RedCharDeviceWriteBuffer *write_buffer_get_client(RedCharDeviceClientOpaque *client,
|
||||
int size);
|
||||
|
||||
/* Returns NULL if use_token == true and no tokens are available */
|
||||
RedCharDeviceWriteBuffer *write_buffer_get_server(int size, bool use_token);
|
||||
|
||||
/* Either add the buffer to the write queue or release it */
|
||||
void write_buffer_add(RedCharDeviceWriteBuffer *write_buf);
|
||||
static void write_buffer_release(RedCharDevice *dev,
|
||||
RedCharDeviceWriteBuffer **p_write_buf);
|
||||
|
||||
SpiceCharDeviceInstance *get_device_instance();
|
||||
|
||||
RedCharDevicePrivate *priv;
|
||||
void ref() { g_object_ref(this); }
|
||||
void unref() { g_object_unref(this); }
|
||||
};
|
||||
|
||||
/* api for specific char devices */
|
||||
|
||||
@ -232,18 +228,8 @@ RedCharDevice *spicevmc_device_connect(RedsState *reds,
|
||||
SpiceCharDeviceInstance *sin,
|
||||
uint8_t channel_type);
|
||||
|
||||
SpiceCharDeviceInstance *red_char_device_get_device_instance(RedCharDevice *dev);
|
||||
|
||||
SpiceCharDeviceInterface *spice_char_device_get_interface(SpiceCharDeviceInstance *instance);
|
||||
|
||||
/* 'SpiceCharDeviceState' name is used for consistency with what spice-char.h exports */
|
||||
struct SpiceCharDeviceState: public GObject
|
||||
{
|
||||
RedCharDevicePrivate *priv;
|
||||
void ref() { g_object_ref(this); }
|
||||
void unref() { g_object_unref(this); }
|
||||
};
|
||||
|
||||
SPICE_END_DECLS
|
||||
|
||||
#endif /* CHAR_DEVICE_H_ */
|
||||
|
||||
@ -113,7 +113,7 @@ stream_device_partial_read(StreamDevice *dev, SpiceCharDeviceInstance *sin)
|
||||
// As calling sif->state here can cause a crash, schedule
|
||||
// a timer and do the call in it. Remove this code when
|
||||
// we are sure all Qemu versions have been patched.
|
||||
RedsState *reds = red_char_device_get_server(dev);
|
||||
RedsState *reds = dev->get_server();
|
||||
if (!dev->close_timer) {
|
||||
dev->close_timer = reds_core_timer_add(reds, close_timer_func, dev);
|
||||
}
|
||||
@ -234,7 +234,7 @@ handle_msg_invalid(StreamDevice *dev, SpiceCharDeviceInstance *sin, const char *
|
||||
|
||||
RedCharDevice *char_dev = dev;
|
||||
RedCharDeviceWriteBuffer *buf =
|
||||
red_char_device_write_buffer_get_server(char_dev, total_size, false);
|
||||
char_dev->write_buffer_get_server(total_size, false);
|
||||
buf->buf_used = total_size;
|
||||
|
||||
StreamDevHeader *const hdr = (StreamDevHeader *)buf->buf;
|
||||
@ -244,7 +244,7 @@ handle_msg_invalid(StreamDevice *dev, SpiceCharDeviceInstance *sin, const char *
|
||||
error->error_code = GUINT32_TO_LE(0);
|
||||
strcpy((char *) error->msg, error_msg);
|
||||
|
||||
red_char_device_write_buffer_add(char_dev, buf);
|
||||
char_dev->write_buffer_add(buf);
|
||||
|
||||
dev->has_error = true;
|
||||
return false;
|
||||
@ -335,7 +335,7 @@ handle_msg_device_display_info(StreamDevice *dev, SpiceCharDeviceInstance *sin)
|
||||
dev->device_display_info.device_address,
|
||||
dev->device_display_info.device_display_id);
|
||||
|
||||
reds_send_device_display_info(red_char_device_get_server(dev));
|
||||
reds_send_device_display_info(dev->get_server());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -571,7 +571,7 @@ stream_device_stream_start(void *opaque, StreamMsgStartStop *start,
|
||||
int total_size = sizeof(StreamDevHeader) + msg_size;
|
||||
|
||||
RedCharDeviceWriteBuffer *buf =
|
||||
red_char_device_write_buffer_get_server(dev, total_size, false);
|
||||
dev->write_buffer_get_server(total_size, false);
|
||||
buf->buf_used = total_size;
|
||||
|
||||
StreamDevHeader *hdr = (StreamDevHeader *)buf->buf;
|
||||
@ -579,7 +579,7 @@ stream_device_stream_start(void *opaque, StreamMsgStartStop *start,
|
||||
|
||||
memcpy(&hdr[1], start, msg_size);
|
||||
|
||||
red_char_device_write_buffer_add(dev, buf);
|
||||
dev->write_buffer_add(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -605,7 +605,7 @@ stream_device_stream_queue_stat(void *opaque, const StreamQueueStat *stats G_GNU
|
||||
// TODO resume flow...
|
||||
// avoid recursion if we need to call get data from data handling from
|
||||
// data handling
|
||||
red_char_device_wakeup(dev);
|
||||
dev->wakeup();
|
||||
}
|
||||
}
|
||||
|
||||
@ -665,7 +665,7 @@ stream_device_create_channel(StreamDevice *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
SpiceServer* reds = red_char_device_get_server(dev);
|
||||
SpiceServer* reds = dev->get_server();
|
||||
SpiceCoreInterfaceInternal* core = reds_get_core_interface(reds);
|
||||
|
||||
int id = reds_get_free_channel_id(reds, SPICE_CHANNEL_DISPLAY);
|
||||
@ -693,7 +693,7 @@ static void
|
||||
char_device_set_state(RedCharDevice *char_dev, int state)
|
||||
{
|
||||
SpiceCharDeviceInstance *sin;
|
||||
sin = red_char_device_get_device_instance(char_dev);
|
||||
sin = char_dev->get_device_instance();
|
||||
spice_assert(sin != NULL);
|
||||
|
||||
SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
|
||||
@ -709,7 +709,7 @@ send_capabilities(RedCharDevice *char_dev)
|
||||
int total_size = sizeof(StreamDevHeader) + msg_size;
|
||||
|
||||
RedCharDeviceWriteBuffer *buf =
|
||||
red_char_device_write_buffer_get_server(char_dev, total_size, false);
|
||||
char_dev->write_buffer_get_server(total_size, false);
|
||||
buf->buf_used = total_size;
|
||||
|
||||
StreamDevHeader *const hdr = (StreamDevHeader *)buf->buf;
|
||||
@ -718,7 +718,7 @@ send_capabilities(RedCharDevice *char_dev)
|
||||
StreamMsgCapabilities *const caps = (StreamMsgCapabilities *)(hdr+1);
|
||||
memset(caps, 0, msg_size);
|
||||
|
||||
red_char_device_write_buffer_add(char_dev, buf);
|
||||
char_dev->write_buffer_add(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -741,7 +741,7 @@ stream_device_port_event(RedCharDevice *char_dev, uint8_t event)
|
||||
dev->msg_pos = 0;
|
||||
dev->has_error = false;
|
||||
dev->flow_stopped = false;
|
||||
red_char_device_reset(char_dev);
|
||||
char_dev->reset();
|
||||
reset_channels(dev);
|
||||
|
||||
// enable the device again. We re-enable it on close as otherwise we don't want to get a
|
||||
|
||||
@ -441,9 +441,9 @@ static void reds_reset_vdp(RedsState *reds)
|
||||
* The tokens are also reset to avoid mismatch in upon agent reconnection.
|
||||
*/
|
||||
dev->priv->agent_attached = FALSE;
|
||||
red_char_device_stop(dev);
|
||||
red_char_device_reset(dev);
|
||||
red_char_device_reset_dev_instance(dev, NULL);
|
||||
dev->stop();
|
||||
dev->reset();
|
||||
dev->reset_dev_instance(NULL);
|
||||
|
||||
sif = spice_char_device_get_interface(reds->vdagent);
|
||||
if (sif->state) {
|
||||
@ -459,9 +459,8 @@ static RedCharDeviceWriteBuffer *vdagent_new_write_buffer(RedCharDeviceVDIPort *
|
||||
uint32_t total_msg_size = sizeof(VDIChunkHeader) + sizeof(VDAgentMessage) + size;
|
||||
|
||||
RedCharDeviceWriteBuffer *char_dev_buf;
|
||||
char_dev_buf = red_char_device_write_buffer_get_server(agent_dev,
|
||||
total_msg_size,
|
||||
use_token);
|
||||
char_dev_buf = agent_dev->write_buffer_get_server(total_msg_size,
|
||||
use_token);
|
||||
if (!char_dev_buf) {
|
||||
return NULL; // no token was available
|
||||
}
|
||||
@ -520,8 +519,8 @@ void reds_client_disconnect(RedsState *reds, RedClient *client)
|
||||
/* note that client might be NULL, if the vdagent was once
|
||||
* up and than was removed */
|
||||
RedCharDeviceClientOpaque *client_opaque = (RedCharDeviceClientOpaque *) client;
|
||||
if (red_char_device_client_exists(reds->agent_dev, client_opaque)) {
|
||||
red_char_device_client_remove(reds->agent_dev, client_opaque);
|
||||
if (reds->agent_dev->client_exists(client_opaque)) {
|
||||
reds->agent_dev->client_remove(client_opaque);
|
||||
}
|
||||
|
||||
reds->clients.remove(client);
|
||||
@ -538,7 +537,7 @@ void reds_client_disconnect(RedsState *reds, RedClient *client)
|
||||
0,
|
||||
false);
|
||||
|
||||
red_char_device_write_buffer_add(reds->agent_dev, char_dev_buf);
|
||||
reds->agent_dev->write_buffer_add(char_dev_buf);
|
||||
}
|
||||
|
||||
/* Reset write filter to start with clean state on client reconnect */
|
||||
@ -729,7 +728,7 @@ static void vdi_port_read_buf_free(RedPipeItem *base)
|
||||
necessary. Note that since we can be called from red_char_device_wakeup
|
||||
this can cause recursion, but we have protection for that */
|
||||
if (buf->dev->priv->agent_attached) {
|
||||
red_char_device_wakeup(buf->dev);
|
||||
buf->dev->wakeup();
|
||||
}
|
||||
g_free(buf);
|
||||
}
|
||||
@ -772,7 +771,7 @@ static RedPipeItem *vdi_port_read_one_msg_from_device(RedCharDevice *self,
|
||||
RedVDIReadBuf *dispatch_buf;
|
||||
int n;
|
||||
|
||||
reds = red_char_device_get_server(self);
|
||||
reds = self->get_server();
|
||||
g_assert(reds->agent_dev == sin->st);
|
||||
if (!reds->vdagent) {
|
||||
return NULL;
|
||||
@ -926,7 +925,7 @@ void reds_send_device_display_info(RedsState *reds)
|
||||
|
||||
reds->pending_device_display_info_message = false;
|
||||
|
||||
red_char_device_write_buffer_add(reds->agent_dev, char_dev_buf);
|
||||
reds->agent_dev->write_buffer_add(char_dev_buf);
|
||||
}
|
||||
|
||||
/* after calling this, we unref the message, and the ref is in the instance side */
|
||||
@ -954,7 +953,7 @@ static void vdi_port_send_tokens_to_client(RedCharDevice *self,
|
||||
|
||||
static void vdi_port_on_free_self_token(RedCharDevice *self)
|
||||
{
|
||||
RedsState *reds = red_char_device_get_server(self);
|
||||
RedsState *reds = self->get_server();
|
||||
|
||||
if (reds->inputs_channel && reds->pending_mouse_event) {
|
||||
spice_debug("pending mouse event");
|
||||
@ -1002,7 +1001,7 @@ void reds_handle_agent_mouse_event(RedsState *reds, const VDAgentMouseState *mou
|
||||
VDInternalBuf *internal_buf = (VDInternalBuf *)char_dev_buf->buf;
|
||||
internal_buf->u.mouse_state = *mouse_state;
|
||||
|
||||
red_char_device_write_buffer_add(reds->agent_dev, char_dev_buf);
|
||||
reds->agent_dev->write_buffer_add(char_dev_buf);
|
||||
}
|
||||
|
||||
SPICE_GNUC_VISIBLE int spice_server_get_num_clients(SpiceServer *reds)
|
||||
@ -1075,16 +1074,14 @@ void reds_on_main_agent_start(RedsState *reds, MainChannelClient *mcc, uint32_t
|
||||
* flow control, but will have no other problem.
|
||||
*/
|
||||
RedCharDeviceClientOpaque *client_opaque = (RedCharDeviceClientOpaque *) client;
|
||||
if (!red_char_device_client_exists(dev_state, client_opaque)) {
|
||||
if (!dev_state->client_exists(client_opaque)) {
|
||||
int client_added;
|
||||
|
||||
client_added = red_char_device_client_add(dev_state,
|
||||
client_opaque,
|
||||
TRUE, /* flow control */
|
||||
REDS_VDI_PORT_NUM_RECEIVE_BUFFS,
|
||||
REDS_AGENT_WINDOW_SIZE,
|
||||
num_tokens,
|
||||
mcc->is_waiting_for_migrate_data());
|
||||
client_added = dev_state->client_add(client_opaque, TRUE,
|
||||
REDS_VDI_PORT_NUM_RECEIVE_BUFFS,
|
||||
REDS_AGENT_WINDOW_SIZE,
|
||||
num_tokens,
|
||||
mcc->is_waiting_for_migrate_data());
|
||||
|
||||
if (!client_added) {
|
||||
spice_warning("failed to add client to agent");
|
||||
@ -1092,9 +1089,7 @@ void reds_on_main_agent_start(RedsState *reds, MainChannelClient *mcc, uint32_t
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
red_char_device_send_to_client_tokens_set(dev_state,
|
||||
client_opaque,
|
||||
num_tokens);
|
||||
dev_state->send_to_client_tokens_set(client_opaque, num_tokens);
|
||||
}
|
||||
|
||||
reds_send_device_display_info(reds);
|
||||
@ -1112,9 +1107,8 @@ void reds_on_main_agent_tokens(RedsState *reds, MainChannelClient *mcc, uint32_t
|
||||
return;
|
||||
}
|
||||
spice_assert(reds->vdagent->st);
|
||||
red_char_device_send_to_client_tokens_add(reds->vdagent->st,
|
||||
(RedCharDeviceClientOpaque *) client,
|
||||
num_tokens);
|
||||
reds->vdagent->st->send_to_client_tokens_add((RedCharDeviceClientOpaque *)client,
|
||||
num_tokens);
|
||||
}
|
||||
|
||||
uint8_t *reds_get_agent_data_buffer(RedsState *reds, MainChannelClient *mcc, size_t size)
|
||||
@ -1136,9 +1130,8 @@ uint8_t *reds_get_agent_data_buffer(RedsState *reds, MainChannelClient *mcc, siz
|
||||
spice_assert(dev->priv->recv_from_client_buf == NULL);
|
||||
client = mcc->get_client();
|
||||
dev->priv->recv_from_client_buf =
|
||||
red_char_device_write_buffer_get_client(dev,
|
||||
(RedCharDeviceClientOpaque *) client,
|
||||
size + sizeof(VDIChunkHeader));
|
||||
dev->write_buffer_get_client((RedCharDeviceClientOpaque *)client,
|
||||
size + sizeof(VDIChunkHeader));
|
||||
/* check if buffer was allocated, as flow control is enabled for
|
||||
* this device this is a normal condition */
|
||||
if (!dev->priv->recv_from_client_buf) {
|
||||
@ -1160,8 +1153,8 @@ void reds_release_agent_data_buffer(RedsState *reds, uint8_t *buf)
|
||||
spice_assert(buf == dev->priv->recv_from_client_buf->buf + sizeof(VDIChunkHeader));
|
||||
/* if we pushed the buffer the buffer is attached to the channel so don't free it */
|
||||
if (!dev->priv->recv_from_client_buf_pushed) {
|
||||
red_char_device_write_buffer_release(dev,
|
||||
&dev->priv->recv_from_client_buf);
|
||||
RedCharDevice::write_buffer_release(dev,
|
||||
&dev->priv->recv_from_client_buf);
|
||||
}
|
||||
dev->priv->recv_from_client_buf = NULL;
|
||||
dev->priv->recv_from_client_buf_pushed = FALSE;
|
||||
@ -1249,7 +1242,7 @@ void reds_on_main_agent_data(RedsState *reds, MainChannelClient *mcc, const void
|
||||
dev->priv->recv_from_client_buf->buf_used = sizeof(VDIChunkHeader) + size;
|
||||
|
||||
dev->priv->recv_from_client_buf_pushed = TRUE;
|
||||
red_char_device_write_buffer_add(dev, dev->priv->recv_from_client_buf);
|
||||
dev->write_buffer_add(dev->priv->recv_from_client_buf);
|
||||
}
|
||||
|
||||
void reds_on_main_migrate_connected(RedsState *reds, int seamless)
|
||||
@ -1346,14 +1339,14 @@ void reds_marshall_migrate_data(RedsState *reds, SpiceMarshaller *m)
|
||||
there is no need to track the client tokens
|
||||
(see reds_reset_vdp) */
|
||||
spice_assert(!agent_dev->priv->agent_attached);
|
||||
red_char_device_migrate_data_marshall_empty(m);
|
||||
RedCharDevice::migrate_data_marshall_empty(m);
|
||||
size_t padding_len = sizeof(SpiceMigrateDataMain) - sizeof(SpiceMigrateDataCharDevice);
|
||||
null_agent_mig_data = spice_marshaller_reserve_space(m, padding_len);
|
||||
memset(null_agent_mig_data, 0, padding_len);
|
||||
return;
|
||||
}
|
||||
|
||||
red_char_device_migrate_data_marshall(agent_dev, m);
|
||||
agent_dev->migrate_data_marshall(m);
|
||||
spice_marshaller_add_uint8(m, agent_dev->priv->client_agent_started);
|
||||
|
||||
mig_data.agent2client.chunk_header = agent_dev->priv->vdi_chunk_header;
|
||||
@ -1473,7 +1466,7 @@ static int reds_agent_state_restore(RedsState *reds, SpiceMigrateDataMain *mig_d
|
||||
agent_dev->priv->read_filter.discard_all,
|
||||
agent_dev->priv->read_filter.msg_data_to_read,
|
||||
agent_dev->priv->read_filter.result);
|
||||
return red_char_device_restore(agent_dev, &mig_data->agent_base);
|
||||
return agent_dev->restore(&mig_data->agent_base);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1524,7 +1517,7 @@ bool reds_handle_migrate_data(RedsState *reds, MainChannelClient *mcc,
|
||||
RedCharDeviceClientOpaque *client_opaque =
|
||||
(RedCharDeviceClientOpaque *) mcc->get_client();
|
||||
/* red_char_device_client_remove disables waiting for migration data */
|
||||
red_char_device_client_remove(agent_dev, client_opaque);
|
||||
agent_dev->client_remove(client_opaque);
|
||||
reds->main_channel->push_agent_connected();
|
||||
}
|
||||
}
|
||||
@ -3089,7 +3082,7 @@ static RedCharDevice *attach_to_red_agent(RedsState *reds, SpiceCharDeviceInstan
|
||||
SpiceCharDeviceInterface *sif;
|
||||
|
||||
dev->priv->agent_attached = true;
|
||||
red_char_device_reset_dev_instance(dev, sin);
|
||||
dev->reset_dev_instance(sin);
|
||||
|
||||
reds->vdagent = sin;
|
||||
reds_update_mouse_mode(reds);
|
||||
@ -3117,16 +3110,12 @@ static RedCharDevice *attach_to_red_agent(RedsState *reds, SpiceCharDeviceInstan
|
||||
*/
|
||||
RedCharDeviceClientOpaque *client_opaque =
|
||||
(RedCharDeviceClientOpaque *) reds_get_client(reds);
|
||||
if (!red_char_device_client_exists(dev, client_opaque)) {
|
||||
if (!dev->client_exists(client_opaque)) {
|
||||
int client_added;
|
||||
|
||||
client_added = red_char_device_client_add(dev,
|
||||
client_opaque,
|
||||
TRUE, /* flow control */
|
||||
REDS_VDI_PORT_NUM_RECEIVE_BUFFS,
|
||||
REDS_AGENT_WINDOW_SIZE,
|
||||
~0,
|
||||
TRUE);
|
||||
client_added = dev->client_add(client_opaque, TRUE,
|
||||
REDS_VDI_PORT_NUM_RECEIVE_BUFFS,
|
||||
REDS_AGENT_WINDOW_SIZE, ~0, TRUE);
|
||||
|
||||
if (!client_added) {
|
||||
spice_warning("failed to add client to agent");
|
||||
@ -3159,7 +3148,7 @@ SPICE_GNUC_VISIBLE void spice_server_char_device_wakeup(SpiceCharDeviceInstance*
|
||||
spice_warning("no RedCharDevice attached to instance %p", sin);
|
||||
return;
|
||||
}
|
||||
red_char_device_wakeup(sin->st);
|
||||
sin->st->wakeup();
|
||||
}
|
||||
|
||||
#define SUBTYPE_VDAGENT "vdagent"
|
||||
@ -3240,7 +3229,7 @@ spice_server_char_device_add_interface(SpiceServer *reds, SpiceBaseInstance *sin
|
||||
/* setting the char_device state to "started" for backward compatibily with
|
||||
* qemu releases that don't call spice api for start/stop (not implemented yet) */
|
||||
if (reds->vm_running) {
|
||||
red_char_device_start(dev_state);
|
||||
dev_state->start();
|
||||
}
|
||||
reds_add_char_device(reds, dev_state);
|
||||
} else {
|
||||
@ -3260,7 +3249,7 @@ static int spice_server_char_device_remove_interface(RedsState *reds, SpiceBaseI
|
||||
g_return_val_if_fail(char_device == reds->vdagent, -1);
|
||||
if (reds->vdagent) {
|
||||
reds_agent_remove(reds);
|
||||
red_char_device_reset_dev_instance(reds->agent_dev, NULL);
|
||||
reds->agent_dev->reset_dev_instance(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3411,7 +3400,7 @@ SPICE_GNUC_VISIBLE int spice_server_remove_interface(SpiceBaseInstance *sin)
|
||||
} else if (strcmp(base_interface->type, SPICE_INTERFACE_CHAR_DEVICE) == 0) {
|
||||
SpiceCharDeviceInstance *char_device = SPICE_UPCAST(SpiceCharDeviceInstance, sin);
|
||||
g_return_val_if_fail(char_device->st != NULL, -1);
|
||||
reds = red_char_device_get_server(char_device->st);
|
||||
reds = char_device->st->get_server();
|
||||
return spice_server_char_device_remove_interface(reds, sin);
|
||||
} else if (strcmp(base_interface->type, SPICE_INTERFACE_QXL) == 0) {
|
||||
QXLInstance *qxl;
|
||||
@ -4314,7 +4303,7 @@ SPICE_GNUC_VISIBLE void spice_server_vm_start(SpiceServer *reds)
|
||||
{
|
||||
reds->vm_running = TRUE;
|
||||
for (auto dev: reds->char_devices) {
|
||||
red_char_device_start(dev);
|
||||
dev->start();
|
||||
}
|
||||
reds_on_vm_start(reds);
|
||||
}
|
||||
@ -4323,7 +4312,7 @@ SPICE_GNUC_VISIBLE void spice_server_vm_stop(SpiceServer *reds)
|
||||
{
|
||||
reds->vm_running = FALSE;
|
||||
for (auto dev: reds->char_devices) {
|
||||
red_char_device_stop(dev);
|
||||
dev->stop();
|
||||
}
|
||||
reds_on_vm_stop(reds);
|
||||
}
|
||||
@ -4519,7 +4508,7 @@ static void red_char_device_vdi_port_constructed(GObject *object)
|
||||
|
||||
G_OBJECT_CLASS(red_char_device_vdi_port_parent_class)->constructed(object);
|
||||
|
||||
reds = red_char_device_get_server(RED_CHAR_DEVICE(object));
|
||||
reds = RED_CHAR_DEVICE(object)->get_server();
|
||||
|
||||
agent_msg_filter_init(&dev->priv->write_filter, reds->config->agent_copypaste,
|
||||
reds->config->agent_file_xfer,
|
||||
@ -4547,7 +4536,7 @@ red_char_device_vdi_port_finalize(GObject *object)
|
||||
RedCharDeviceVDIPort *dev = RED_CHAR_DEVICE_VDIPORT(object);
|
||||
|
||||
/* make sure we have no other references to RedVDIReadBuf buffers */
|
||||
red_char_device_reset(dev);
|
||||
dev->reset();
|
||||
if (dev->priv->current_read_buf) {
|
||||
red_pipe_item_unref(&dev->priv->current_read_buf->base);
|
||||
dev->priv->current_read_buf = NULL;
|
||||
|
||||
@ -83,8 +83,8 @@ SmartCardChannelClient::alloc_recv_buf(uint16_t type, uint32_t size)
|
||||
spice_assert(smartcard_char_device_get_client(smartcard) || priv->smartcard);
|
||||
spice_assert(!priv->write_buf);
|
||||
priv->write_buf =
|
||||
red_char_device_write_buffer_get_client(smartcard,
|
||||
(RedCharDeviceClientOpaque *) this, size);
|
||||
smartcard->write_buffer_get_client((RedCharDeviceClientOpaque *)this,
|
||||
size);
|
||||
|
||||
if (!priv->write_buf) {
|
||||
spice_error("failed to allocate write buffer");
|
||||
@ -108,8 +108,8 @@ SmartCardChannelClient::release_recv_buf(uint16_t type, uint32_t size, uint8_t *
|
||||
} else {
|
||||
if (priv->write_buf) { /* msg hasn't been pushed to the guest */
|
||||
spice_assert(priv->write_buf->buf == msg);
|
||||
red_char_device_write_buffer_release(priv->smartcard,
|
||||
&priv->write_buf);
|
||||
RedCharDevice::write_buffer_release(priv->smartcard,
|
||||
&priv->write_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,9 +257,7 @@ void smartcard_char_device_notify_reader_add(RedCharDeviceSmartcard *dev)
|
||||
RedCharDeviceWriteBuffer *write_buf;
|
||||
VSCMsgHeader *vheader;
|
||||
|
||||
write_buf = red_char_device_write_buffer_get_server(dev,
|
||||
sizeof(*vheader),
|
||||
true);
|
||||
write_buf = dev->write_buffer_get_server(sizeof(*vheader), true);
|
||||
if (!write_buf) {
|
||||
spice_error("failed to allocate write buffer");
|
||||
return;
|
||||
@ -281,13 +279,8 @@ void smartcard_char_device_attach_client(SpiceCharDeviceInstance *char_device,
|
||||
spice_assert(!smartcard_channel_client_get_char_device(scc) && !dev->priv->scc);
|
||||
dev->priv->scc = scc;
|
||||
smartcard_channel_client_set_char_device(scc, dev);
|
||||
client_added = red_char_device_client_add(dev,
|
||||
(RedCharDeviceClientOpaque *) scc,
|
||||
FALSE, /* no flow control yet */
|
||||
0, /* send queue size */
|
||||
~0,
|
||||
~0,
|
||||
scc->is_waiting_for_migrate_data());
|
||||
client_added = dev->client_add((RedCharDeviceClientOpaque *)scc, FALSE, 0,
|
||||
~0, ~0, scc->is_waiting_for_migrate_data());
|
||||
if (!client_added) {
|
||||
spice_warning("failed");
|
||||
dev->priv->scc = NULL;
|
||||
@ -310,9 +303,7 @@ gboolean smartcard_char_device_notify_reader_remove(RedCharDeviceSmartcard *dev)
|
||||
spice_debug("reader add was never sent to the device");
|
||||
return FALSE;
|
||||
}
|
||||
write_buf = red_char_device_write_buffer_get_server(dev,
|
||||
sizeof(*vheader),
|
||||
true);
|
||||
write_buf = dev->write_buffer_get_server(sizeof(*vheader), true);
|
||||
if (!write_buf) {
|
||||
spice_error("failed to allocate write buffer");
|
||||
return FALSE;
|
||||
@ -333,11 +324,11 @@ void smartcard_char_device_detach_client(RedCharDeviceSmartcard *smartcard,
|
||||
SpiceCharDeviceInterface *sif;
|
||||
SpiceCharDeviceInstance *sin;
|
||||
|
||||
sin = red_char_device_get_device_instance(smartcard);
|
||||
sin = smartcard->get_device_instance();
|
||||
sif = spice_char_device_get_interface(sin);
|
||||
|
||||
spice_assert(smartcard->priv->scc == scc);
|
||||
red_char_device_client_remove(smartcard, (RedCharDeviceClientOpaque *) scc);
|
||||
smartcard->client_remove((RedCharDeviceClientOpaque *)scc);
|
||||
smartcard_channel_client_set_char_device(scc, NULL);
|
||||
smartcard->priv->scc = NULL;
|
||||
|
||||
@ -371,13 +362,13 @@ static void smartcard_channel_send_migrate_data(SmartCardChannelClient *scc,
|
||||
spice_marshaller_add_uint32(m, SPICE_MIGRATE_DATA_SMARTCARD_VERSION);
|
||||
|
||||
if (!dev) {
|
||||
red_char_device_migrate_data_marshall_empty(m);
|
||||
RedCharDevice::migrate_data_marshall_empty(m);
|
||||
spice_marshaller_add_uint8(m, 0);
|
||||
spice_marshaller_add_uint32(m, 0);
|
||||
spice_marshaller_add_uint32(m, 0);
|
||||
spice_debug("null char dev");
|
||||
} else {
|
||||
red_char_device_migrate_data_marshall(dev, m);
|
||||
dev->migrate_data_marshall(m);
|
||||
spice_marshaller_add_uint8(m, dev->priv->reader_added);
|
||||
spice_marshaller_add_uint32(m, dev->priv->buf_used);
|
||||
m2 = spice_marshaller_get_ptr_submarshaller(m);
|
||||
@ -449,7 +440,7 @@ void smartcard_channel_write_to_reader(RedCharDeviceWriteBuffer *write_buf)
|
||||
write_buf->buf_used = actual_length + sizeof(VSCMsgHeader);
|
||||
/* pushing the buffer to the write queue; It will be released
|
||||
* when it will be fully consumed by the device */
|
||||
red_char_device_write_buffer_add(sin->st, write_buf);
|
||||
sin->st->write_buffer_add(write_buf);
|
||||
}
|
||||
|
||||
static void smartcard_device_restore_partial_read(RedCharDeviceSmartcard *dev,
|
||||
@ -475,7 +466,7 @@ int smartcard_char_device_handle_migrate_data(RedCharDeviceSmartcard *smartcard,
|
||||
smartcard->priv->reader_added = mig_data->reader_added;
|
||||
|
||||
smartcard_device_restore_partial_read(smartcard, mig_data);
|
||||
return red_char_device_restore(smartcard, &mig_data->base);
|
||||
return smartcard->restore(&mig_data->base);
|
||||
}
|
||||
|
||||
void RedSmartcardChannel::on_connect(RedClient *client, RedStream *stream, int migration,
|
||||
|
||||
@ -159,7 +159,7 @@ RedVmcChannel::RedVmcChannel(RedsState *reds, uint32_t type, uint32_t id):
|
||||
|
||||
RedVmcChannel::~RedVmcChannel()
|
||||
{
|
||||
red_char_device_write_buffer_release(chardev, &recv_from_client_buf);
|
||||
RedCharDevice::write_buffer_release(chardev, &recv_from_client_buf);
|
||||
if (pipe_item) {
|
||||
red_pipe_item_unref(&pipe_item->base);
|
||||
}
|
||||
@ -350,11 +350,12 @@ void VmcChannelClient::on_disconnect()
|
||||
channel = get_channel();
|
||||
|
||||
/* partial message which wasn't pushed to device */
|
||||
red_char_device_write_buffer_release(channel->chardev, &channel->recv_from_client_buf);
|
||||
RedCharDevice::write_buffer_release(channel->chardev,
|
||||
&channel->recv_from_client_buf);
|
||||
|
||||
if (channel->chardev) {
|
||||
if (red_char_device_client_exists(channel->chardev, (RedCharDeviceClientOpaque *) client)) {
|
||||
red_char_device_client_remove(channel->chardev, (RedCharDeviceClientOpaque *) client);
|
||||
if (channel->chardev->client_exists((RedCharDeviceClientOpaque *)client)) {
|
||||
channel->chardev->client_remove((RedCharDeviceClientOpaque *)client);
|
||||
} else {
|
||||
red_channel_warning(channel,
|
||||
"client %p have already been removed from char dev %p",
|
||||
@ -392,7 +393,7 @@ bool VmcChannelClient::handle_migrate_data(uint32_t size, void *message)
|
||||
spice_error("bad header");
|
||||
return FALSE;
|
||||
}
|
||||
return red_char_device_restore(channel->chardev, &mig_data->base);
|
||||
return channel->chardev->restore(&mig_data->base);
|
||||
}
|
||||
|
||||
static bool handle_compressed_msg(RedVmcChannel *channel, RedChannelClient *rcc,
|
||||
@ -402,9 +403,8 @@ static bool handle_compressed_msg(RedVmcChannel *channel, RedChannelClient *rcc,
|
||||
int decompressed_size;
|
||||
RedCharDeviceWriteBuffer *write_buf;
|
||||
|
||||
write_buf = red_char_device_write_buffer_get_server(channel->chardev,
|
||||
compressed_data_msg->uncompressed_size,
|
||||
false);
|
||||
write_buf = channel->chardev->write_buffer_get_server(compressed_data_msg->uncompressed_size,
|
||||
false);
|
||||
if (!write_buf) {
|
||||
return FALSE;
|
||||
}
|
||||
@ -424,16 +424,16 @@ static bool handle_compressed_msg(RedVmcChannel *channel, RedChannelClient *rcc,
|
||||
#endif
|
||||
default:
|
||||
spice_warning("Invalid Compression Type");
|
||||
red_char_device_write_buffer_release(channel->chardev, &write_buf);
|
||||
RedCharDevice::write_buffer_release(channel->chardev, &write_buf);
|
||||
return FALSE;
|
||||
}
|
||||
if (decompressed_size != compressed_data_msg->uncompressed_size) {
|
||||
spice_warning("Decompression Error");
|
||||
red_char_device_write_buffer_release(channel->chardev, &write_buf);
|
||||
RedCharDevice::write_buffer_release(channel->chardev, &write_buf);
|
||||
return FALSE;
|
||||
}
|
||||
write_buf->buf_used = decompressed_size;
|
||||
red_char_device_write_buffer_add(channel->chardev, write_buf);
|
||||
channel->chardev->write_buffer_add(write_buf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -452,7 +452,7 @@ bool VmcChannelClient::handle_message(uint16_t type, uint32_t size, void *msg)
|
||||
spice_assert(channel->recv_from_client_buf->buf == msg);
|
||||
stat_inc_counter(channel->in_data, size);
|
||||
channel->recv_from_client_buf->buf_used = size;
|
||||
red_char_device_write_buffer_add(channel->chardev, channel->recv_from_client_buf);
|
||||
channel->chardev->write_buffer_add(channel->recv_from_client_buf);
|
||||
channel->recv_from_client_buf = NULL;
|
||||
break;
|
||||
case SPICE_MSGC_SPICEVMC_COMPRESSED_DATA:
|
||||
@ -491,8 +491,8 @@ uint8_t *VmcChannelClient::alloc_recv_buf(uint16_t type, uint32_t size)
|
||||
|
||||
assert(!channel->recv_from_client_buf);
|
||||
|
||||
channel->recv_from_client_buf = red_char_device_write_buffer_get_server(channel->chardev,
|
||||
size, true);
|
||||
channel->recv_from_client_buf = channel->chardev->write_buffer_get_server(size,
|
||||
true);
|
||||
if (!channel->recv_from_client_buf) {
|
||||
block_read();
|
||||
return NULL;
|
||||
@ -513,7 +513,8 @@ void VmcChannelClient::release_recv_buf(uint16_t type, uint32_t size, uint8_t *m
|
||||
case SPICE_MSGC_SPICEVMC_DATA: {
|
||||
RedVmcChannel *channel = get_channel();
|
||||
/* buffer wasn't pushed to device */
|
||||
red_char_device_write_buffer_release(channel->chardev, &channel->recv_from_client_buf);
|
||||
RedCharDevice::write_buffer_release(channel->chardev,
|
||||
&channel->recv_from_client_buf);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -556,7 +557,7 @@ static void spicevmc_red_channel_send_data(VmcChannelClient *rcc,
|
||||
channel->queued_data -= i->buf_used;
|
||||
if (channel->chardev &&
|
||||
old_queued_data >= QUEUED_DATA_LIMIT && channel->queued_data < QUEUED_DATA_LIMIT) {
|
||||
red_char_device_wakeup(channel->chardev);
|
||||
channel->chardev->wakeup();
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,7 +572,7 @@ static void spicevmc_red_channel_send_migrate_data(VmcChannelClient *rcc,
|
||||
spice_marshaller_add_uint32(m, SPICE_MIGRATE_DATA_SPICEVMC_MAGIC);
|
||||
spice_marshaller_add_uint32(m, SPICE_MIGRATE_DATA_SPICEVMC_VERSION);
|
||||
|
||||
red_char_device_migrate_data_marshall(channel->chardev, m);
|
||||
channel->chardev->migrate_data_marshall(m);
|
||||
}
|
||||
|
||||
static void spicevmc_red_channel_send_port_init(RedChannelClient *rcc,
|
||||
@ -657,9 +658,7 @@ void RedVmcChannel::on_connect(RedClient *client, RedStream *stream, int migrati
|
||||
spicevmc_port_send_init(rcc);
|
||||
}
|
||||
|
||||
if (!red_char_device_client_add(vmc_channel->chardev, (RedCharDeviceClientOpaque *) client,
|
||||
FALSE, 0, ~0, ~0,
|
||||
rcc->is_waiting_for_migrate_data())) {
|
||||
if (!vmc_channel->chardev->client_add((RedCharDeviceClientOpaque *)client, FALSE, 0, ~0, ~0, rcc->is_waiting_for_migrate_data())) {
|
||||
spice_warning("failed to add client to spicevmc");
|
||||
rcc->disconnect();
|
||||
return;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user