[Spice-devel] [PATCH] !fixup char-device: add 'self' param to vfuncs

Jonathon Jongsma jjongsma at redhat.com
Tue Nov 1 16:42:07 UTC 2016


---
This patch removes the 'opaque' property from RedCharDevice and the 'opaque'
argument from the char device vfuncs. It required some
minor refactoring to achieve this.

 server/char-device.c              | 31 ++-----------
 server/char-device.h              | 15 ++----
 server/reds.c                     | 16 +++----
 server/smartcard-channel-client.c |  2 +-
 server/smartcard.c                | 11 ++---
 server/spicevmc.c                 | 97 ++++++++++++++++++++++++++++++---------
 6 files changed, 96 insertions(+), 76 deletions(-)

diff --git a/server/char-device.c b/server/char-device.c
index 8ed1a2a..41b6960 100644
--- a/server/char-device.c
+++ b/server/char-device.c
@@ -66,7 +66,6 @@ struct RedCharDevicePrivate {
     int during_read_from_device;
     int during_write_to_device;
 
-    void *opaque;
     SpiceServer *reds;
 };
 
@@ -88,7 +87,6 @@ enum {
     PROP_SPICE_SERVER,
     PROP_CLIENT_TOKENS_INTERVAL,
     PROP_SELF_TOKENS,
-    PROP_OPAQUE
 };
 
 static void red_char_device_write_buffer_unref(RedCharDeviceWriteBuffer *write_buf);
@@ -99,7 +97,7 @@ red_char_device_read_one_msg_from_device(RedCharDevice *dev)
 {
    RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
 
-   return klass->read_one_msg_from_device(dev, dev->priv->sin, dev->priv->opaque);
+   return klass->read_one_msg_from_device(dev, dev->priv->sin);
 }
 
 static void
@@ -109,7 +107,7 @@ red_char_device_send_msg_to_client(RedCharDevice *dev,
 {
    RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
 
-   klass->send_msg_to_client(dev, msg, client, dev->priv->opaque);
+   klass->send_msg_to_client(dev, msg, client);
 }
 
 static void
@@ -119,7 +117,7 @@ red_char_device_send_tokens_to_client(RedCharDevice *dev,
 {
    RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
 
-   klass->send_tokens_to_client(dev, client, tokens, dev->priv->opaque);
+   klass->send_tokens_to_client(dev, client, tokens);
 }
 
 static void
@@ -128,7 +126,7 @@ red_char_device_on_free_self_token(RedCharDevice *dev)
    RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
 
    if (klass->on_free_self_token != NULL) {
-       klass->on_free_self_token(dev->priv->opaque);
+       klass->on_free_self_token(dev);
    }
 }
 
@@ -137,7 +135,7 @@ red_char_device_remove_client(RedCharDevice *dev, RedClient *client)
 {
    RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
 
-   klass->remove_client(dev, client, dev->priv->opaque);
+   klass->remove_client(dev, client);
 }
 
 static void red_char_device_write_buffer_free(RedCharDeviceWriteBuffer *buf)
@@ -686,11 +684,6 @@ void red_char_device_reset_dev_instance(RedCharDevice *dev,
     g_object_notify(G_OBJECT(dev), "sin");
 }
 
-void *red_char_device_opaque_get(RedCharDevice *dev)
-{
-    return dev->priv->opaque;
-}
-
 void red_char_device_destroy(RedCharDevice *char_dev)
 {
     g_return_if_fail(RED_IS_CHAR_DEVICE(char_dev));
@@ -1039,9 +1032,6 @@ red_char_device_get_property(GObject    *object,
         case PROP_SELF_TOKENS:
             g_value_set_uint64(value, self->priv->num_self_tokens);
             break;
-        case PROP_OPAQUE:
-            g_value_set_pointer(value, self->priv->opaque);
-            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
     }
@@ -1069,9 +1059,6 @@ red_char_device_set_property(GObject      *object,
         case PROP_SELF_TOKENS:
             self->priv->num_self_tokens = g_value_get_uint64(value);
             break;
-        case PROP_OPAQUE:
-            self->priv->opaque = g_value_get_pointer(value);
-            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
     }
@@ -1154,14 +1141,6 @@ red_char_device_class_init(RedCharDeviceClass *klass)
                                                         0, G_MAXUINT64, 0,
                                                         G_PARAM_STATIC_STRINGS |
                                                         G_PARAM_READWRITE));
-    g_object_class_install_property(object_class,
-                                    PROP_OPAQUE,
-                                    g_param_spec_pointer("opaque",
-                                                         "opaque",
-                                                         "User data to pass to callbacks",
-                                                      G_PARAM_STATIC_STRINGS |
-                                                      G_PARAM_READWRITE));
-
 }
 
 static void
diff --git a/server/char-device.h b/server/char-device.h
index 14cbe94..3b87023 100644
--- a/server/char-device.h
+++ b/server/char-device.h
@@ -57,29 +57,26 @@ struct RedCharDeviceClass
     /* reads from the device till reaching a msg that should be sent to the client,
      * or till the reading fails */
     RedPipeItem* (*read_one_msg_from_device)(RedCharDevice *self,
-                                             SpiceCharDeviceInstance *sin,
-                                             void *opaque);
+                                             SpiceCharDeviceInstance *sin);
     /* after this call, the message is unreferenced */
     void (*send_msg_to_client)(RedCharDevice *self,
                                RedPipeItem *msg,
-                               RedClient *client,
-                               void *opaque);
+                               RedClient *client);
 
     /* The cb is called when a predefined number of write buffers were consumed by the
      * device */
     void (*send_tokens_to_client)(RedCharDevice *self,
                                   RedClient *client,
-                                  uint32_t tokens,
-                                  void *opaque);
+                                  uint32_t tokens);
 
     /* 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);
+    void (*on_free_self_token)(RedCharDevice *self);
 
     /* This cb is called if it is recommended to remove the client
      * 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)(RedCharDevice *self, RedClient *client, void *opaque);
+    void (*remove_client)(RedCharDevice *self, RedClient *client);
 };
 
 GType red_char_device_get_type(void) G_GNUC_CONST;
@@ -164,8 +161,6 @@ void red_char_device_reset_dev_instance(RedCharDevice *dev,
                                         SpiceCharDeviceInstance *sin);
 void red_char_device_destroy(RedCharDevice *dev);
 
-void *red_char_device_opaque_get(RedCharDevice *dev);
-
 /* only one client is supported */
 void red_char_device_migrate_data_marshall(RedCharDevice *dev,
                                            SpiceMarshaller *m);
diff --git a/server/reds.c b/server/reds.c
index 0cc5665..7b8f361 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -824,8 +824,7 @@ static void vdi_port_read_buf_free(RedPipeItem *base)
 /* reads from the device till completes reading a message that is addressed to the client,
  * or otherwise, when reading from the device fails */
 static RedPipeItem *vdi_port_read_one_msg_from_device(RedCharDevice *self,
-                                                      SpiceCharDeviceInstance *sin,
-                                                      void *opaque)
+                                                      SpiceCharDeviceInstance *sin)
 {
     RedsState *reds;
     RedCharDeviceVDIPort *dev = RED_CHAR_DEVICE_VDIPORT(self);
@@ -903,8 +902,7 @@ static RedPipeItem *vdi_port_read_one_msg_from_device(RedCharDevice *self,
 /* after calling this, we unref the message, and the ref is in the instance side */
 static void vdi_port_send_msg_to_client(RedCharDevice *self,
                                         RedPipeItem *msg,
-                                        RedClient *client,
-                                        void *opaque)
+                                        RedClient *client)
 {
     RedVDIReadBuf *agent_data_buf = (RedVDIReadBuf *)msg;
 
@@ -918,16 +916,15 @@ static void vdi_port_send_msg_to_client(RedCharDevice *self,
 
 static void vdi_port_send_tokens_to_client(RedCharDevice *self,
                                            RedClient *client,
-                                           uint32_t tokens,
-                                           void *opaque)
+                                           uint32_t tokens)
 {
     main_channel_client_push_agent_tokens(red_client_get_main(client),
                                           tokens);
 }
 
-static void vdi_port_on_free_self_token(void *opaque)
+static void vdi_port_on_free_self_token(RedCharDevice *self)
 {
-    RedsState *reds = opaque;
+    RedsState *reds = red_char_device_get_server(self);
 
     if (reds->inputs_channel && reds->pending_mouse_event) {
         spice_debug("pending mouse event");
@@ -936,8 +933,7 @@ static void vdi_port_on_free_self_token(void *opaque)
 }
 
 static void vdi_port_remove_client(RedCharDevice *self,
-                                   RedClient *client,
-                                   void *opaque)
+                                   RedClient *client)
 {
     red_channel_client_shutdown(RED_CHANNEL_CLIENT(red_client_get_main(client)));
 }
diff --git a/server/smartcard-channel-client.c b/server/smartcard-channel-client.c
index 30b2249..d00a6b2 100644
--- a/server/smartcard-channel-client.c
+++ b/server/smartcard-channel-client.c
@@ -273,7 +273,7 @@ static void smartcard_channel_client_remove_reader(SmartCardChannelClient *scc,
         return;
     }
 
-    dev = red_char_device_opaque_get(char_device->st);
+    dev = RED_CHAR_DEVICE_SMARTCARD(char_device->st);
     spice_assert(scc->priv->smartcard == dev);
     if (!smartcard_char_device_notify_reader_remove(dev)) {
         smartcard_channel_client_push_error(RED_CHANNEL_CLIENT(scc),
diff --git a/server/smartcard.c b/server/smartcard.c
index ed083d8..bc1ada4 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -150,8 +150,7 @@ static void smartcard_read_buf_prepare(RedCharDeviceSmartcard *dev, VSCMsgHeader
 }
 
 static RedPipeItem *smartcard_read_msg_from_device(RedCharDevice *self,
-                                                   SpiceCharDeviceInstance *sin,
-                                                   void *opaque)
+                                                   SpiceCharDeviceInstance *sin)
 {
     RedCharDeviceSmartcard *dev = RED_CHAR_DEVICE_SMARTCARD(self);
     SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
@@ -189,8 +188,7 @@ static RedPipeItem *smartcard_read_msg_from_device(RedCharDevice *self,
 
 static void smartcard_send_msg_to_client(RedCharDevice *self,
                                          RedPipeItem *msg,
-                                         RedClient *client,
-                                         void *opaque)
+                                         RedClient *client)
 {
     RedCharDeviceSmartcard *dev = RED_CHAR_DEVICE_SMARTCARD(self);
     RedChannelClient *rcc = RED_CHANNEL_CLIENT(dev->priv->scc);
@@ -203,13 +201,12 @@ static void smartcard_send_msg_to_client(RedCharDevice *self,
 
 static void smartcard_send_tokens_to_client(RedCharDevice *self,
                                             RedClient *client,
-                                            uint32_t tokens,
-                                            void *opaque)
+                                            uint32_t tokens)
 {
     spice_error("not implemented");
 }
 
-static void smartcard_remove_client(RedCharDevice *self, RedClient *client, void *opaque)
+static void smartcard_remove_client(RedCharDevice *self, RedClient *client)
 {
     RedCharDeviceSmartcard *dev = RED_CHAR_DEVICE_SMARTCARD(self);
     RedChannelClient *rcc = RED_CHANNEL_CLIENT(dev->priv->scc);
diff --git a/server/spicevmc.c b/server/spicevmc.c
index 99e5b6e..c4551ed 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -88,10 +88,13 @@ struct RedCharDeviceSpiceVmcPrivate {
     RedChannel *channel;
 };
 
+typedef struct RedVmcChannel RedVmcChannel;
+typedef struct RedVmcChannelClass RedVmcChannelClass;
+
 static GType red_char_device_spicevmc_get_type(void) G_GNUC_CONST;
 static RedCharDevice *red_char_device_spicevmc_new(SpiceCharDeviceInstance *sin,
                                                    RedsState *reds,
-                                                   void *opaque);
+                                                   RedVmcChannel *vmc_channel);
 
 G_DEFINE_TYPE(RedCharDeviceSpiceVmc, red_char_device_spicevmc, RED_TYPE_CHAR_DEVICE)
 
@@ -109,9 +112,6 @@ G_DEFINE_TYPE(RedCharDeviceSpiceVmc, red_char_device_spicevmc, RED_TYPE_CHAR_DEV
 #define RED_VMC_CHANNEL_GET_CLASS(obj) \
     (G_TYPE_INSTANCE_GET_CLASS((obj), RED_TYPE_VMC_CHANNEL, RedVmcChannelClass))
 
-typedef struct RedVmcChannel RedVmcChannel;
-typedef struct RedVmcChannelClass RedVmcChannelClass;
-
 struct RedVmcChannel
 {
     RedChannel parent;
@@ -358,10 +358,10 @@ static RedVmcPipeItem* try_compress_lz4(RedVmcChannel *state, int n, RedVmcPipeI
 #endif
 
 static RedPipeItem *spicevmc_chardev_read_msg_from_dev(RedCharDevice *self,
-                                                       SpiceCharDeviceInstance *sin,
-                                                       void *opaque)
+                                                       SpiceCharDeviceInstance *sin)
 {
-    RedVmcChannel *state = opaque;
+    RedCharDeviceSpiceVmc *vmc = RED_CHAR_DEVICE_SPICEVMC(self);
+    RedVmcChannel *state = RED_VMC_CHANNEL(vmc->priv->channel);
     SpiceCharDeviceInterface *sif;
     RedVmcPipeItem *msg_item;
     int n;
@@ -405,10 +405,10 @@ static RedPipeItem *spicevmc_chardev_read_msg_from_dev(RedCharDevice *self,
 
 static void spicevmc_chardev_send_msg_to_client(RedCharDevice *self,
                                                 RedPipeItem *msg,
-                                                RedClient *client,
-                                                void *opaque)
+                                                RedClient *client)
 {
-    RedVmcChannel *state = opaque;
+    RedCharDeviceSpiceVmc *vmc = RED_CHAR_DEVICE_SPICEVMC(self);
+    RedVmcChannel *state = RED_VMC_CHANNEL(vmc->priv->channel);
 
     spice_assert(red_channel_client_get_client(state->rcc) == client);
     red_pipe_item_ref(msg);
@@ -444,16 +444,16 @@ static void spicevmc_port_send_event(RedChannelClient *rcc, uint8_t event)
 
 static void spicevmc_char_dev_send_tokens_to_client(RedCharDevice *self,
                                                     RedClient *client,
-                                                    uint32_t tokens,
-                                                    void *opaque)
+                                                    uint32_t tokens)
 {
     spice_printerr("Not implemented!");
 }
 
 static void spicevmc_char_dev_remove_client(RedCharDevice *self,
-                                            RedClient *client, void *opaque)
+                                            RedClient *client)
 {
-    RedVmcChannel *state = opaque;
+    RedCharDeviceSpiceVmc *vmc = RED_CHAR_DEVICE_SPICEVMC(self);
+    RedVmcChannel *state = RED_VMC_CHANNEL(vmc->priv->channel);
 
     spice_printerr("vmc state %p, client %p", state, client);
     spice_assert(state->rcc &&
@@ -779,6 +779,7 @@ red_vmc_channel_class_init(RedVmcChannelClass *klass)
     channel_class->handle_migrate_flush_mark = spicevmc_channel_client_handle_migrate_flush_mark;
     channel_class->handle_migrate_data = spicevmc_channel_client_handle_migrate_data;
 
+
     g_object_class_install_property(object_class,
                                     PROP_DEVICE_INSTANCE,
                                     g_param_spec_pointer("device-instance",
@@ -877,10 +878,8 @@ RedCharDevice *spicevmc_device_connect(RedsState *reds,
 /* Must be called from RedClient handling thread. */
 void spicevmc_device_disconnect(RedsState *reds, SpiceCharDeviceInstance *sin)
 {
-    RedVmcChannel *state;
-
-    /* FIXME */
-    state = (RedVmcChannel *)red_char_device_opaque_get((RedCharDevice*)sin->st);
+    RedCharDeviceSpiceVmc *device = RED_CHAR_DEVICE_SPICEVMC(sin->st);
+    RedVmcChannel *state = RED_VMC_CHANNEL(device->priv->channel);
 
     red_char_device_write_buffer_release(state->chardev, &state->recv_from_client_buf);
     /* FIXME */
@@ -896,14 +895,15 @@ void spicevmc_device_disconnect(RedsState *reds, SpiceCharDeviceInstance *sin)
 SPICE_GNUC_VISIBLE void spice_server_port_event(SpiceCharDeviceInstance *sin, uint8_t event)
 {
     RedVmcChannel *state;
+    RedCharDeviceSpiceVmc *device = RED_CHAR_DEVICE_SPICEVMC(sin->st);
 
     if (sin->st == NULL) {
         spice_warning("no SpiceCharDeviceState attached to instance %p", sin);
         return;
     }
 
-    /* FIXME */
-    state = (RedVmcChannel *)red_char_device_opaque_get((RedCharDevice*)sin->st);
+    state = RED_VMC_CHANNEL(device->priv->channel);
+
     if (event == SPICE_PORT_EVENT_OPENED) {
         state->port_opened = TRUE;
     } else if (event == SPICE_PORT_EVENT_CLOSED) {
@@ -925,6 +925,48 @@ red_char_device_spicevmc_dispose(GObject *object)
     g_clear_object(&self->priv->channel);
 }
 
+enum {
+    PROP_CHAR_DEVICE_0,
+    PROP_CHAR_DEVICE_CHANNEL,
+};
+
+static void
+red_char_device_spicevmc_get_property(GObject *object,
+                                      guint property_id,
+                                      GValue *value,
+                                      GParamSpec *pspec)
+{
+    RedCharDeviceSpiceVmc *self = RED_CHAR_DEVICE_SPICEVMC(object);
+
+    switch (property_id)
+    {
+        case PROP_CHAR_DEVICE_CHANNEL:
+            g_value_set_object(value, self->priv->channel);
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+    }
+}
+
+static void
+red_char_device_spicevmc_set_property(GObject *object,
+                                      guint property_id,
+                                      const GValue *value,
+                                      GParamSpec *pspec)
+{
+    RedCharDeviceSpiceVmc *self = RED_CHAR_DEVICE_SPICEVMC(object);
+
+    switch (property_id)
+    {
+        case PROP_CHAR_DEVICE_CHANNEL:
+            g_clear_object(&self->priv->channel);
+            self->priv->channel = g_value_dup_object(value);
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+    }
+}
+
 static void
 red_char_device_spicevmc_class_init(RedCharDeviceSpiceVmcClass *klass)
 {
@@ -934,11 +976,22 @@ red_char_device_spicevmc_class_init(RedCharDeviceSpiceVmcClass *klass)
     g_type_class_add_private(klass, sizeof (RedCharDeviceSpiceVmcPrivate));
 
     object_class->dispose = red_char_device_spicevmc_dispose;
+    object_class->get_property = red_char_device_spicevmc_get_property;
+    object_class->set_property = red_char_device_spicevmc_set_property;
 
     char_dev_class->read_one_msg_from_device = spicevmc_chardev_read_msg_from_dev;
     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;
+
+    g_object_class_install_property(object_class,
+                                    PROP_CHAR_DEVICE_CHANNEL,
+                                    g_param_spec_pointer("channel",
+                                                         "channel",
+                                                         "Channel associated with the char device",
+                                                         G_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY |
+                                                         G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -949,13 +1002,13 @@ red_char_device_spicevmc_init(RedCharDeviceSpiceVmc *self)
 static RedCharDevice *
 red_char_device_spicevmc_new(SpiceCharDeviceInstance *sin,
                              RedsState *reds,
-                             void *opaque)
+                             RedVmcChannel *vmc_channel)
 {
     return g_object_new(RED_TYPE_CHAR_DEVICE_SPICEVMC,
                         "sin", sin,
                         "spice-server", reds,
                         "client-tokens-interval", 0ULL,
                         "self-tokens", ~0ULL,
-                        "opaque", opaque,
+                        "channel", vmc_channel,
                         NULL);
 }
-- 
2.7.4



More information about the Spice-devel mailing list