[Spice-devel] [PATCH 01/14] Move RedCharDeviceCallbacks into RedCharDeviceClass

Jonathon Jongsma jjongsma at redhat.com
Fri Apr 8 16:23:09 UTC 2016


This patch has already merged

On Thu, 2016-04-07 at 17:11 -0500, Jonathon Jongsma wrote:
> 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);
>  }


More information about the Spice-devel mailing list