[Spice-devel] [PATCH 12/12] Move SpiceCharDeviceCallbacks into RedCharDeviceClass
Frediano Ziglio
fziglio at redhat.com
Mon Mar 21 11:24:28 UTC 2016
From: Christophe Fergeau <cfergeau at redhat.com>
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 | 72 ++++++++++++++++++++++++++--------------------------
server/char-device.h | 71 +++++++++++++++++++++++----------------------------
server/reds.c | 35 +++++++++++--------------
server/smartcard.c | 20 +++++++--------
server/spicevmc.c | 36 +++++++++++---------------
5 files changed, 108 insertions(+), 126 deletions(-)
diff --git a/server/char-device.c b/server/char-device.c
index 2c82453..20c4ad8 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,30 +113,36 @@ typedef struct SpiceCharDeviceMsgToClientItem {
static SpiceCharDeviceMsgToClient *
spice_char_device_read_one_msg_from_device(SpiceCharDeviceState *dev)
{
- g_return_val_if_fail(dev != NULL, NULL);
- g_return_val_if_fail(dev->priv->cbs.read_one_msg_from_device != NULL, NULL);
+ RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
- return dev->priv->cbs.read_one_msg_from_device(dev->priv->sin, dev->priv->opaque);
+ g_return_val_if_fail(RED_IS_CHAR_DEVICE(dev), NULL);
+ g_return_val_if_fail(klass->read_one_msg_from_device != NULL, NULL);
+
+ 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)
{
- g_return_val_if_fail(dev != NULL, NULL);
- g_return_val_if_fail(dev->priv->cbs.ref_msg_to_client != NULL, NULL);
+ RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
+
+ g_return_val_if_fail(RED_IS_CHAR_DEVICE(dev), NULL);
+ g_return_val_if_fail(klass->ref_msg_to_client != NULL, NULL);
- return dev->priv->cbs.ref_msg_to_client(msg, dev->priv->opaque);
+ return klass->ref_msg_to_client(msg, dev->priv->opaque);
}
static void
spice_char_device_unref_msg_to_client(SpiceCharDeviceState *dev,
SpiceCharDeviceMsgToClient *msg)
{
- g_return_if_fail(dev != NULL);
- g_return_if_fail(dev->priv->cbs.unref_msg_to_client != NULL);
+ RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
+
+ g_return_if_fail(RED_IS_CHAR_DEVICE(dev));
+ g_return_if_fail(klass->unref_msg_to_client != NULL);
- dev->priv->cbs.unref_msg_to_client(msg, dev->priv->opaque);
+ klass->unref_msg_to_client(msg, dev->priv->opaque);
}
static void
@@ -145,10 +150,12 @@ spice_char_device_send_msg_to_client(SpiceCharDeviceState *dev,
SpiceCharDeviceMsgToClient *msg,
RedClient *client)
{
- g_return_if_fail(dev != NULL);
- g_return_if_fail(dev->priv->cbs.send_msg_to_client != NULL);
+ RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
- dev->priv->cbs.send_msg_to_client(msg, client, dev->priv->opaque);
+ g_return_if_fail(RED_IS_CHAR_DEVICE(dev));
+ g_return_if_fail(klass->send_msg_to_client != NULL);
+
+ klass->send_msg_to_client(msg, client, dev->priv->opaque);
}
static void
@@ -156,28 +163,35 @@ spice_char_device_send_tokens_to_client(SpiceCharDeviceState *dev,
RedClient *client,
uint32_t tokens)
{
- g_return_if_fail(dev != NULL);
- g_return_if_fail(dev->priv->cbs.send_tokens_to_client != NULL);
+ RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
+
+ g_return_if_fail(RED_IS_CHAR_DEVICE(dev));
+ g_return_if_fail(klass->send_tokens_to_client != NULL);
- dev->priv->cbs.send_tokens_to_client(client, tokens, dev->priv->opaque);
+ klass->send_tokens_to_client(client, tokens, dev->priv->opaque);
}
static void
spice_char_device_on_free_self_token(SpiceCharDeviceState *dev)
{
- g_return_if_fail(dev != NULL);
- 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);
+
+ g_return_if_fail(RED_IS_CHAR_DEVICE(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)
{
- g_return_if_fail(dev != NULL);
- g_return_if_fail(dev->priv->cbs.remove_client != NULL);
+ RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
+
+ g_return_if_fail(RED_IS_CHAR_DEVICE(dev));
+ g_return_if_fail(klass->remove_client != NULL);
- dev->priv->cbs.remove_client(client, dev->priv->opaque);
+ klass->remove_client(client, dev->priv->opaque);
}
static void spice_char_device_write_buffer_free(SpiceCharDeviceWriteBuffer *buf)
@@ -1261,17 +1275,3 @@ red_char_device_init(RedCharDevice *self)
g_signal_connect(self, "notify::sin", G_CALLBACK(red_char_device_on_sin_changed), NULL);
}
-
-/* FIXME: 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 d0fc63c..207c6d5 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 7be0f61..f0f08bd 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 fc27bfe..910afc2 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 9a009b9..c5434c1 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);
}
--
2.5.5
More information about the Spice-devel
mailing list