@@ -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 \
@@ -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);
@@ -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.
new file mode 100644
@@ -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++;
+
+ 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;
+}
new file mode 100644
@@ -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__
+
+#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
@@ -88,6 +88,7 @@ typedef struct ErrorItem {
VSCMsgError error;
} ErrorItem;
+
typedef struct MsgItem {
PipeItem base;
uint32_t refs;