[Spice-devel] [PATCH 01/14] Move RedCharDeviceCallbacks into RedCharDeviceClass
Jonathon Jongsma
jjongsma at redhat.com
Thu Apr 7 22:11:14 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 | 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 693e8bb..e17e3be 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;
- RedCharDeviceCallbacks cbs;
void *opaque;
SpiceServer *reds;
};
@@ -106,21 +105,27 @@ typedef struct RedCharDeviceMsgToClientItem {
static RedCharDeviceMsgToClient *
red_char_device_read_one_msg_from_device(RedCharDevice *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 RedCharDeviceMsgToClient *
red_char_device_ref_msg_to_client(RedCharDevice *dev,
RedCharDeviceMsgToClient *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
red_char_device_unref_msg_to_client(RedCharDevice *dev,
RedCharDeviceMsgToClient *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
@@ -128,7 +133,9 @@ red_char_device_send_msg_to_client(RedCharDevice *dev,
RedCharDeviceMsgToClient *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
@@ -136,21 +143,27 @@ red_char_device_send_tokens_to_client(RedCharDevice *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
red_char_device_on_free_self_token(RedCharDevice *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
red_char_device_remove_client(RedCharDevice *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 red_char_device_write_buffer_free(RedCharDeviceWriteBuffer *buf)
@@ -1234,17 +1247,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,
- RedCharDeviceCallbacks *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 020aa1a..f4d6283 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 RedCharDeviceMsgToClient;
+
#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))
@@ -48,15 +50,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 */
+ RedCharDeviceMsgToClient* (*read_one_msg_from_device)(SpiceCharDeviceInstance *sin,
+ void *opaque);
+ RedCharDeviceMsgToClient* (*ref_msg_to_client)(RedCharDeviceMsgToClient *msg,
+ void *opaque);
+ void (*unref_msg_to_client)(RedCharDeviceMsgToClient *msg,
+ void *opaque);
+ void (*send_msg_to_client)(RedCharDeviceMsgToClient *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 RedCharDeviceCallbacks RedCharDeviceCallbacks;
-void red_char_device_set_callbacks(RedCharDevice *dev,
- RedCharDeviceCallbacks *cbs,
- gpointer opaque);
-
/*
* Shared code for char devices, mainly for flow control.
*
@@ -133,40 +160,6 @@ typedef struct RedCharDeviceWriteBuffer {
uint32_t refs;
} RedCharDeviceWriteBuffer;
-typedef void RedCharDeviceMsgToClient;
-
-struct RedCharDeviceCallbacks {
- /*
- * 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 */
- RedCharDeviceMsgToClient* (*read_one_msg_from_device)(SpiceCharDeviceInstance *sin,
- void *opaque);
- RedCharDeviceMsgToClient* (*ref_msg_to_client)(RedCharDeviceMsgToClient *msg,
- void *opaque);
- void (*unref_msg_to_client)(RedCharDeviceMsgToClient *msg,
- void *opaque);
- void (*send_msg_to_client)(RedCharDeviceMsgToClient *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 red_char_device_reset_dev_instance(RedCharDevice *dev,
SpiceCharDeviceInstance *sin);
void red_char_device_destroy(RedCharDevice *dev);
diff --git a/server/reds.c b/server/reds.c
index 9283288..e3f479d 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -4322,33 +4322,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;
- RedCharDeviceCallbacks 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 8d382ce..ba6f2f5 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -272,14 +272,6 @@ static SpiceCharDeviceInstance *smartcard_readers_get_unattached(void)
static RedCharDeviceSmartcard *smartcard_device_new(RedsState *reds, SpiceCharDeviceInstance *sin)
{
RedCharDevice *char_dev;
- RedCharDeviceCallbacks 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,
@@ -288,8 +280,8 @@ static RedCharDeviceSmartcard *smartcard_device_new(RedsState *reds, SpiceCharDe
"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);
}
@@ -869,10 +861,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 cb8bcc6..1c41845 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -611,6 +611,14 @@ SPICE_GNUC_VISIBLE void spice_server_port_event(SpiceCharDeviceInstance *sin, ui
static void
red_char_device_spicevmc_class_init(RedCharDeviceSpiceVmcClass *klass)
{
+ RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass);
+
+ 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
@@ -623,25 +631,11 @@ red_char_device_spicevmc_new(SpiceCharDeviceInstance *sin,
RedsState *reds,
void *opaque)
{
- RedCharDevice *char_dev;
- RedCharDeviceCallbacks 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.4.11
More information about the Spice-devel
mailing list