[Spice-devel] [PATCH 03/14] Introduce simple RedPipeItem class

Jonathon Jongsma jjongsma at redhat.com
Fri Apr 8 20:13:48 UTC 2016


On Thu, 2016-04-07 at 17:11 -0500, Jonathon Jongsma wrote:
> From: Christophe Fergeau <cfergeau at redhat.com>
> 
> This is similar to PipeItem (which is a type id + a RingItem linked list
> member), except that it's refcounted. A user-defined callback is called
> when the refcount drops to 0.

It's not so much "like" a PipeItem -- it actually "contains" a PipeItem or
"inherits" from PipeItem.

> Refcounted is open coded for several classes deriving from PipeItem, so

I'm unfamiliar with the term "open coded". Is that a reference to the fact that
the ref/unref functions take a void* argument? If so, I'm not sure that I like
that idea very much, though I do admit that it probably makes usage a bit more
convenient...

> this base class will help to share this code, and allow to remove some
> ref/unref virtual functions in some interfaces when we can assume every
> instance derives from this base class.

A bit more information about why this class is useful and how it will be used in
the future would be nice here (I'm sure it will become obvious as I look at
future patches...)

> ---
>  server/Makefile.am     |  2 ++
>  server/red-channel.c   |  6 -----
>  server/red-channel.h   | 13 +---------
>  server/red-pipe-item.c | 65
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  server/red-pipe-item.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++
>  server/smartcard.c     |  1 +
>  6 files changed, 129 insertions(+), 18 deletions(-)
>  create mode 100644 server/red-pipe-item.c
>  create mode 100644 server/red-pipe-item.h
> 
> diff --git a/server/Makefile.am b/server/Makefile.am
> index a7a8d9f..a119c86 100644
> --- a/server/Makefile.am
> +++ b/server/Makefile.am
> @@ -112,6 +112,8 @@ libserver_la_SOURCES =				\
>  	display-channel.h			\
>  	cursor-channel.c			\
>  	cursor-channel.h			\
> +	red-pipe-item.c				\
> +	red-pipe-item.h				\
>  	reds.c					\
>  	reds.h					\
>  	reds-private.h				\
> diff --git a/server/red-channel.c b/server/red-channel.c
> index d8f1d27..dcec39e 100644
> --- a/server/red-channel.c
> +++ b/server/red-channel.c
> @@ -1658,12 +1658,6 @@ void
> red_channel_client_set_message_serial(RedChannelClient *rcc, uint64_t seria
>      rcc->send_data.serial = serial;
>  }
>  
> -void pipe_item_init(PipeItem *item, int type)
> -{
> -    ring_item_init(&item->link);
> -    item->type = type;
> -}
> -
>  static inline gboolean client_pipe_add(RedChannelClient *rcc, PipeItem *item,
> RingItem *pos)
>  {
>      spice_assert(rcc && item);
> diff --git a/server/red-channel.h b/server/red-channel.h
> index 94b09eb..3c762ff 100644
> --- a/server/red-channel.h
> +++ b/server/red-channel.h
> @@ -33,6 +33,7 @@
>  #include "demarshallers.h"
>  #include "reds-stream.h"
>  #include "stat.h"
> +#include "red-pipe-item.h"
>  
>  #define MAX_SEND_BUFS 1000
>  #define CLIENT_ACK_WINDOW 20
> @@ -147,16 +148,6 @@ enum {
>      PIPE_ITEM_TYPE_CHANNEL_BASE=101,
>  };
>  
> -typedef struct PipeItem {
> -    RingItem link;
> -    int type;
> -} PipeItem;
> -
> -static inline int pipe_item_is_linked(PipeItem *item)
> -{
> -    return ring_item_is_linked(&item->link);
> -}
> -
>  typedef uint8_t *(*channel_alloc_msg_recv_buf_proc)(RedChannelClient
> *channel,
>                                                      uint16_t type, uint32_t
> size);
>  typedef int (*channel_handle_parsed_proc)(RedChannelClient *rcc, uint32_t
> size, uint16_t type,
> @@ -473,8 +464,6 @@ int red_channel_client_get_roundtrip_ms(RedChannelClient
> *rcc);
>   */
>  void red_channel_client_start_connectivity_monitoring(RedChannelClient *rcc,
> uint32_t timeout_ms);
>  
> -void pipe_item_init(PipeItem *item, int type);
> -
>  // TODO: add back the channel_pipe_add functionality - by adding reference
> counting
>  // to the PipeItem.
>  
> diff --git a/server/red-pipe-item.c b/server/red-pipe-item.c
> new file mode 100644
> index 0000000..a9ebfda
> --- /dev/null
> +++ b/server/red-pipe-item.c
> @@ -0,0 +1,65 @@
> +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> +/*
> +   Copyright (C) 2015 Red Hat, Inc.
> +
> +   This library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   This library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with this library; if not, see <http://www.gnu.org/licenses/
> >.
> +*/
> +#include <config.h>
> +
> +#include "red-channel.h"
> +#include "red-pipe-item.h"
> +
> +void pipe_item_init(PipeItem *item, int type)
> +{
> +    ring_item_init(&item->link);
> +    item->type = type;
> +}
> +
> +RedPipeItem *red_pipe_item_ref(gpointer object)
> +{
> +    RedPipeItem *item = object;
> +
> +    g_return_val_if_fail(item->refcount > 0, NULL);
> +
> +    item->refcount++;

Should we make these refcounts thread-safe?

> +
> +    return item;
> +}
> +
> +void red_pipe_item_unref(gpointer object)
> +{
> +    RedPipeItem *item = object;
> +
> +    g_return_if_fail(item->refcount > 0);
> +
> +    item->refcount--;
> +    if (item->refcount == 0) {
> +        if (item->free_func) {
> +            item->free_func(item);
> +        } else {
> +            free(item);
> +        }
> +    }
> +}
> +
> +void red_pipe_item_init(RedPipeItem *item,
> +                        gint type,
> +                        GDestroyNotify free_func)
> +{
> +    g_return_if_fail(item->refcount == 0);
> +
> +    pipe_item_init(&item->parent, type);
> +    item->refcount = 1;
> +    item->free_func = free_func;
> +}
> diff --git a/server/red-pipe-item.h b/server/red-pipe-item.h
> new file mode 100644
> index 0000000..7bc5abc
> --- /dev/null
> +++ b/server/red-pipe-item.h
> @@ -0,0 +1,60 @@
> +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
> +/*
> +   Copyright (C) 2015 Red Hat, Inc.
> +
> +   This library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   This library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with this library; if not, see <http://www.gnu.org/licenses/
> >.
> +*/
> +#ifndef __RED_MINI_OBJECT_H__
> +#define __RED_MINI_OBJECT_H__

This symbol is probably left over from a previous iteration? Not a big deal, but
probably should match the file name.

> +
> +#include <glib.h>
> +
> +typedef struct PipeItem {
> +    RingItem link;
> +    int type;
> +} PipeItem;
> +
> +static inline int pipe_item_is_linked(PipeItem *item)
> +{
> +    return ring_item_is_linked(&item->link);
> +}
> +
> +void pipe_item_init(PipeItem *item, int type);
> +
> +/* Refcounted pipe item */
> +/* Future goals are to:
> + * - merge it with PipeItem
> + * - stop having RingItem embedded at the beginning of the PipeItem base
> class
> + *   but instead have:
> + *   {
> + *       int type;
> + *       int refcount;
> + *       PipeItem link;
> + *   }
> + *   or even drop PipeItem, and use a GList in RedChannel
> + */
> +typedef struct {
> +    PipeItem parent;
> +
> +    /* private */
> +    int refcount;
> +
> +    GDestroyNotify free_func;
> +} RedPipeItem;
> +
> +RedPipeItem *red_pipe_item_ref(gpointer item);
> +void red_pipe_item_unref(gpointer item);
> +void red_pipe_item_init(RedPipeItem *item, int type, GDestroyNotify
> free_func);
> +
> +#endif
> diff --git a/server/smartcard.c b/server/smartcard.c
> index eb68a8b..557a622 100644
> --- a/server/smartcard.c
> +++ b/server/smartcard.c
> @@ -88,6 +88,7 @@ typedef struct ErrorItem {
>      VSCMsgError  error;
>  } ErrorItem;
>  
> +

unrelated whitespace 

>  typedef struct MsgItem {
>      PipeItem base;
>      uint32_t refs;



Reviewed-by: Jonathon Jongsma <jjongsma at redhat.com>


More information about the Spice-devel mailing list