From abdf484c697a3efb328b9c4b2eb0a6b03f8e9884 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Wed, 23 Mar 2016 12:48:39 +0000 Subject: Move SpiceCharDeviceCallbacks into RedCharDeviceClass This structure holding virtual function pointers was kept until now as a RedCharDevice member in order to make the GObject conversion easier. Now that all RedCharDevice children are converted to GObject, it can be moved into RedCharDeviceClass. --- server/char-device.c | 45 ++++++++++++++++----------------- server/char-device.h | 71 +++++++++++++++++++++++----------------------------- server/reds.c | 35 +++++++++++--------------- server/smartcard.c | 20 +++++++-------- server/spicevmc.c | 36 +++++++++++--------------- 5 files changed, 94 insertions(+), 113 deletions(-) diff --git a/server/char-device.c b/server/char-device.c index e1004d8b..c9c20958 100644 --- a/server/char-device.c +++ b/server/char-device.c @@ -69,7 +69,6 @@ struct RedCharDevicePrivate { int during_read_from_device; int during_write_to_device; - SpiceCharDeviceCallbacks cbs; void *opaque; SpiceServer *reds; }; @@ -114,21 +113,27 @@ typedef struct SpiceCharDeviceMsgToClientItem { static SpiceCharDeviceMsgToClient * spice_char_device_read_one_msg_from_device(SpiceCharDeviceState *dev) { - return dev->priv->cbs.read_one_msg_from_device(dev->priv->sin, dev->priv->opaque); + RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev); + + return klass->read_one_msg_from_device(dev->priv->sin, dev->priv->opaque); } static SpiceCharDeviceMsgToClient * spice_char_device_ref_msg_to_client(SpiceCharDeviceState *dev, SpiceCharDeviceMsgToClient *msg) { - return dev->priv->cbs.ref_msg_to_client(msg, dev->priv->opaque); + RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev); + + return klass->ref_msg_to_client(msg, dev->priv->opaque); } static void spice_char_device_unref_msg_to_client(SpiceCharDeviceState *dev, SpiceCharDeviceMsgToClient *msg) { - dev->priv->cbs.unref_msg_to_client(msg, dev->priv->opaque); + RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev); + + klass->unref_msg_to_client(msg, dev->priv->opaque); } static void @@ -136,7 +141,9 @@ spice_char_device_send_msg_to_client(SpiceCharDeviceState *dev, SpiceCharDeviceMsgToClient *msg, RedClient *client) { - dev->priv->cbs.send_msg_to_client(msg, client, dev->priv->opaque); + RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev); + + klass->send_msg_to_client(msg, client, dev->priv->opaque); } static void @@ -144,21 +151,27 @@ spice_char_device_send_tokens_to_client(SpiceCharDeviceState *dev, RedClient *client, uint32_t tokens) { - dev->priv->cbs.send_tokens_to_client(client, tokens, dev->priv->opaque); + RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev); + + klass->send_tokens_to_client(client, tokens, dev->priv->opaque); } static void spice_char_device_on_free_self_token(SpiceCharDeviceState *dev) { - if (dev->priv->cbs.on_free_self_token != NULL) { - dev->priv->cbs.on_free_self_token(dev->priv->opaque); + RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev); + + if (klass->on_free_self_token != NULL) { + klass->on_free_self_token(dev->priv->opaque); } } static void spice_char_device_remove_client(SpiceCharDeviceState *dev, RedClient *client) { - dev->priv->cbs.remove_client(client, dev->priv->opaque); + RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev); + + klass->remove_client(client, dev->priv->opaque); } static void spice_char_device_write_buffer_free(SpiceCharDeviceWriteBuffer *buf) @@ -1244,17 +1257,3 @@ red_char_device_init(RedCharDevice *self) g_signal_connect(self, "notify::sin", G_CALLBACK(red_char_device_on_sin_changed), NULL); } - -/* TODO: needs to be moved to class vfuncs once all child classes are gobjects */ -void -red_char_device_set_callbacks(RedCharDevice *dev, - SpiceCharDeviceCallbacks *cbs, - gpointer opaque) -{ - g_assert(cbs->read_one_msg_from_device && cbs->ref_msg_to_client && - cbs->unref_msg_to_client && cbs->send_msg_to_client && - cbs->send_tokens_to_client && cbs->remove_client); - - dev->priv->cbs = *cbs; - dev->priv->opaque = opaque; -} diff --git a/server/char-device.h b/server/char-device.h index d0fc63c7..207c6d5e 100644 --- a/server/char-device.h +++ b/server/char-device.h @@ -24,6 +24,8 @@ #include "red-channel.h" #include "migration-protocol.h" +typedef void SpiceCharDeviceMsgToClient; + #define RED_TYPE_CHAR_DEVICE red_char_device_get_type() #define RED_CHAR_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), RED_TYPE_CHAR_DEVICE, RedCharDevice)) @@ -47,15 +49,40 @@ struct SpiceCharDeviceState struct RedCharDeviceClass { GObjectClass parent_class; + + /* + * Messages that are addressed to the client can be queued in case we have + * multiple clients and some of them don't have enough tokens. + */ + + /* reads from the device till reaching a msg that should be sent to the client, + * or till the reading fails */ + SpiceCharDeviceMsgToClient* (*read_one_msg_from_device)(SpiceCharDeviceInstance *sin, + void *opaque); + SpiceCharDeviceMsgToClient* (*ref_msg_to_client)(SpiceCharDeviceMsgToClient *msg, + void *opaque); + void (*unref_msg_to_client)(SpiceCharDeviceMsgToClient *msg, + void *opaque); + void (*send_msg_to_client)(SpiceCharDeviceMsgToClient *msg, + RedClient *client, + void *opaque); /* after this call, the message is unreferenced */ + + /* The cb is called when a predefined number of write buffers were consumed by the + * device */ + void (*send_tokens_to_client)(RedClient *client, uint32_t tokens, void *opaque); + + /* The cb is called when a server (self) message that was addressed to the device, + * has been completely written to it */ + void (*on_free_self_token)(void *opaque); + + /* This cb is called if it is recommanded that a client will be removed + * due to slow flow or due to some other error. + * The called instance should disconnect the client, or at least the corresponding channel */ + void (*remove_client)(RedClient *client, void *opaque); }; GType red_char_device_get_type(void) G_GNUC_CONST; -typedef struct SpiceCharDeviceCallbacks SpiceCharDeviceCallbacks; -void red_char_device_set_callbacks(RedCharDevice *dev, - SpiceCharDeviceCallbacks *cbs, - gpointer opaque); - /* * Shared code for char devices, mainly for flow control. * @@ -127,40 +154,6 @@ typedef struct SpiceCharDeviceWriteBuffer { uint32_t refs; } SpiceCharDeviceWriteBuffer; -typedef void SpiceCharDeviceMsgToClient; - -struct SpiceCharDeviceCallbacks { - /* - * Messages that are addressed to the client can be queued in case we have - * multiple clients and some of them don't have enough tokens. - */ - - /* reads from the device till reaching a msg that should be sent to the client, - * or till the reading fails */ - SpiceCharDeviceMsgToClient* (*read_one_msg_from_device)(SpiceCharDeviceInstance *sin, - void *opaque); - SpiceCharDeviceMsgToClient* (*ref_msg_to_client)(SpiceCharDeviceMsgToClient *msg, - void *opaque); - void (*unref_msg_to_client)(SpiceCharDeviceMsgToClient *msg, - void *opaque); - void (*send_msg_to_client)(SpiceCharDeviceMsgToClient *msg, - RedClient *client, - void *opaque); /* after this call, the message is unreferenced */ - - /* The cb is called when a predefined number of write buffers were consumed by the - * device */ - void (*send_tokens_to_client)(RedClient *client, uint32_t tokens, void *opaque); - - /* The cb is called when a server (self) message that was addressed to the device, - * has been completely written to it */ - void (*on_free_self_token)(void *opaque); - - /* This cb is called if it is recommanded that a client will be removed - * due to slow flow or due to some other error. - * The called instance should disconnect the client, or at least the corresponding channel */ - void (*remove_client)(RedClient *client, void *opaque); -}; - void spice_char_device_state_reset_dev_instance(SpiceCharDeviceState *dev, SpiceCharDeviceInstance *sin); void spice_char_device_state_destroy(SpiceCharDeviceState *dev); diff --git a/server/reds.c b/server/reds.c index a8cc5da2..e32dbd2e 100644 --- a/server/reds.c +++ b/server/reds.c @@ -4337,33 +4337,28 @@ static void red_char_device_vdi_port_class_init(RedCharDeviceVDIPortClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); + RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass); g_type_class_add_private(klass, sizeof (RedCharDeviceVDIPortPrivate)); object_class->finalize = red_char_device_vdi_port_finalize; object_class->constructed = red_char_device_vdi_port_constructed; + + char_dev_class->read_one_msg_from_device = vdi_port_read_one_msg_from_device; + char_dev_class->ref_msg_to_client = vdi_port_ref_msg_to_client; + char_dev_class->unref_msg_to_client = vdi_port_unref_msg_to_client; + char_dev_class->send_msg_to_client = vdi_port_send_msg_to_client; + char_dev_class->send_tokens_to_client = vdi_port_send_tokens_to_client; + char_dev_class->remove_client = vdi_port_remove_client; + char_dev_class->on_free_self_token = vdi_port_on_free_self_token; } static RedCharDeviceVDIPort *red_char_device_vdi_port_new(RedsState *reds) { - RedCharDevice *char_dev; - SpiceCharDeviceCallbacks char_dev_cbs = { - .read_one_msg_from_device = vdi_port_read_one_msg_from_device, - .ref_msg_to_client = vdi_port_ref_msg_to_client, - .unref_msg_to_client = vdi_port_unref_msg_to_client, - .send_msg_to_client = vdi_port_send_msg_to_client, - .send_tokens_to_client = vdi_port_send_tokens_to_client, - .remove_client = vdi_port_remove_client, - .on_free_self_token = vdi_port_on_free_self_token, - }; - - char_dev = g_object_new(RED_TYPE_CHAR_DEVICE_VDIPORT, - "spice-server", reds, - "client-tokens-interval", REDS_TOKENS_TO_SEND, - "self-tokens", REDS_NUM_INTERNAL_AGENT_MESSAGES, - NULL); - - red_char_device_set_callbacks(RED_CHAR_DEVICE(char_dev), - &char_dev_cbs, reds); - return RED_CHAR_DEVICE_VDIPORT(char_dev); + return g_object_new(RED_TYPE_CHAR_DEVICE_VDIPORT, + "spice-server", reds, + "client-tokens-interval", REDS_TOKENS_TO_SEND, + "self-tokens", REDS_NUM_INTERNAL_AGENT_MESSAGES, + "opaque", reds, + NULL); } diff --git a/server/smartcard.c b/server/smartcard.c index fc27bfec..910afc2b 100644 --- a/server/smartcard.c +++ b/server/smartcard.c @@ -275,14 +275,6 @@ static SpiceCharDeviceInstance *smartcard_readers_get_unattached(void) static SmartCardDeviceState *smartcard_device_state_new(RedsState *reds, SpiceCharDeviceInstance *sin) { RedCharDevice *char_dev; - SpiceCharDeviceCallbacks char_dev_cbs = { - .read_one_msg_from_device = smartcard_read_msg_from_device, - .ref_msg_to_client = smartcard_ref_msg_to_client, - .unref_msg_to_client = smartcard_unref_msg_to_client, - .send_msg_to_client = smartcard_send_msg_to_client, - .send_tokens_to_client = smartcard_send_tokens_to_client, - .remove_client = smartcard_remove_client, - }; char_dev = g_object_new(RED_TYPE_CHAR_DEVICE_SMARTCARD, "sin", sin, @@ -291,8 +283,8 @@ static SmartCardDeviceState *smartcard_device_state_new(RedsState *reds, SpiceCh "self-tokens", ~0ULL, NULL); - red_char_device_set_callbacks(RED_CHAR_DEVICE(char_dev), - &char_dev_cbs, char_dev); + g_object_set(char_dev, "opaque", char_dev, NULL); + return RED_CHAR_DEVICE_SMARTCARD(char_dev); } @@ -872,10 +864,18 @@ static void red_char_device_smartcard_class_init(RedCharDeviceSmartcardClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); + RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass); g_type_class_add_private(klass, sizeof (RedCharDeviceSmartcardPrivate)); object_class->finalize = red_char_device_smartcard_finalize; + + char_dev_class->read_one_msg_from_device = smartcard_read_msg_from_device; + char_dev_class->ref_msg_to_client = smartcard_ref_msg_to_client; + char_dev_class->unref_msg_to_client = smartcard_unref_msg_to_client; + char_dev_class->send_msg_to_client = smartcard_send_msg_to_client; + char_dev_class->send_tokens_to_client = smartcard_send_tokens_to_client; + char_dev_class->remove_client = smartcard_remove_client; } static void diff --git a/server/spicevmc.c b/server/spicevmc.c index 9a009b99..c5434c10 100644 --- a/server/spicevmc.c +++ b/server/spicevmc.c @@ -624,10 +624,18 @@ static void red_char_device_spicevmc_class_init(RedCharDeviceSpiceVmcClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); + RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass); g_type_class_add_private(klass, sizeof (RedCharDeviceSpiceVmcPrivate)); object_class->finalize = red_char_device_spicevmc_finalize; + + char_dev_class->read_one_msg_from_device = spicevmc_chardev_read_msg_from_dev; + char_dev_class->ref_msg_to_client = spicevmc_chardev_ref_msg_to_client; + char_dev_class->unref_msg_to_client = spicevmc_chardev_unref_msg_to_client; + char_dev_class->send_msg_to_client = spicevmc_chardev_send_msg_to_client; + char_dev_class->send_tokens_to_client = spicevmc_char_dev_send_tokens_to_client; + char_dev_class->remove_client = spicevmc_char_dev_remove_client; } static void @@ -641,25 +649,11 @@ red_char_device_spicevmc_new(SpiceCharDeviceInstance *sin, RedsState *reds, void *opaque) { - RedCharDevice *char_dev; - SpiceCharDeviceCallbacks char_dev_cbs = { - .read_one_msg_from_device = spicevmc_chardev_read_msg_from_dev, - .ref_msg_to_client = spicevmc_chardev_ref_msg_to_client, - .unref_msg_to_client = spicevmc_chardev_unref_msg_to_client, - .send_msg_to_client = spicevmc_chardev_send_msg_to_client, - .send_tokens_to_client = spicevmc_char_dev_send_tokens_to_client, - .remove_client = spicevmc_char_dev_remove_client, - }; - - char_dev = g_object_new(RED_TYPE_CHAR_DEVICE_SPICEVMC, - "sin", sin, - "spice-server", reds, - "client-tokens-interval", 0ULL, - "self-tokens", ~0ULL, - "opaque", opaque, - NULL); - - red_char_device_set_callbacks(RED_CHAR_DEVICE(char_dev), - &char_dev_cbs, opaque); - return char_dev; + return g_object_new(RED_TYPE_CHAR_DEVICE_SPICEVMC, + "sin", sin, + "spice-server", reds, + "client-tokens-interval", 0ULL, + "self-tokens", ~0ULL, + "opaque", opaque, + NULL); } -- cgit v1.2.3