summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorFrediano Ziglio <freddy77@gmail.com>2020-06-05 16:59:02 +0100
committerFrediano Ziglio <freddy77@gmail.com>2020-07-13 19:48:08 +0100
commitdd9b78fd7843b31886efb37454d4cdf0c63095e7 (patch)
tree035625c650cdc9fe3bae2d22bfb41f1e3a9f4674 /server
parent22fc6a48e65b75fbd1dc90c63bdb0df54c6b72e1 (diff)
Use smart pointers for RedPipeItem
Reduces usage of manual reference counting. Avoids usage of new and use instead red::make_shared to both create and own pipe items. Use move semantic to reduce useless copies. Signed-off-by: Frediano Ziglio <freddy77@gmail.com> Acked-by: Julien Ropé <jrope@gmail.com>
Diffstat (limited to 'server')
-rw-r--r--server/cache-item.tmpl.cpp2
-rw-r--r--server/char-device.cpp7
-rw-r--r--server/char-device.h3
-rw-r--r--server/cursor-channel.cpp10
-rw-r--r--server/dcc.cpp65
-rw-r--r--server/dcc.h6
-rw-r--r--server/inputs-channel.cpp4
-rw-r--r--server/main-channel-client.cpp92
-rw-r--r--server/main-channel-client.h8
-rw-r--r--server/red-channel-client.cpp58
-rw-r--r--server/red-channel-client.h15
-rw-r--r--server/red-channel.cpp16
-rw-r--r--server/red-channel.h4
-rw-r--r--server/red-pipe-item.cpp2
-rw-r--r--server/red-stream-device.cpp4
-rw-r--r--server/red-stream-device.h2
-rw-r--r--server/reds.cpp63
-rw-r--r--server/smartcard-channel-client.cpp2
-rw-r--r--server/smartcard.cpp37
-rw-r--r--server/smartcard.h2
-rw-r--r--server/sound.cpp6
-rw-r--r--server/spicevmc.cpp69
-rw-r--r--server/stream-channel.cpp6
-rw-r--r--server/video-stream.cpp23
-rw-r--r--server/video-stream.h2
25 files changed, 230 insertions, 278 deletions
diff --git a/server/cache-item.tmpl.cpp b/server/cache-item.tmpl.cpp
index 3a24ee33..781f3f53 100644
--- a/server/cache-item.tmpl.cpp
+++ b/server/cache-item.tmpl.cpp
@@ -78,7 +78,7 @@ static void FUNC_NAME(remove)(CHANNELCLIENT *channel_client, RedCacheItem *item)
new (pipe_item) RedCachePipeItem();
pipe_item->inval_one.id = id;
- channel_client->pipe_add_tail(pipe_item); // for now
+ channel_client->pipe_add_tail(RedPipeItemPtr(pipe_item)); // for now
}
static int FUNC_NAME(add)(CHANNELCLIENT *channel_client, uint64_t id, size_t size)
diff --git a/server/char-device.cpp b/server/char-device.cpp
index 762a4939..9423820b 100644
--- a/server/char-device.cpp
+++ b/server/char-device.cpp
@@ -253,9 +253,7 @@ static bool red_char_device_read_from_device(RedCharDevice *dev)
* All messages will be discarded if no client is attached to the device
*/
while ((max_send_tokens || (dev->priv->clients == NULL)) && dev->priv->running) {
- RedPipeItem *msg;
-
- msg = dev->read_one_msg_from_device();
+ auto msg = dev->read_one_msg_from_device();
if (!msg) {
if (dev->priv->during_read_from_device > 1) {
dev->priv->during_read_from_device = 1;
@@ -265,8 +263,7 @@ static bool red_char_device_read_from_device(RedCharDevice *dev)
break;
}
did_read = TRUE;
- red_char_device_send_msg_to_clients(dev, msg);
- red_pipe_item_unref(msg);
+ red_char_device_send_msg_to_clients(dev, msg.get());
max_send_tokens--;
}
dev->priv->during_read_from_device = 0;
diff --git a/server/char-device.h b/server/char-device.h
index 3b0866b1..dce9ab8a 100644
--- a/server/char-device.h
+++ b/server/char-device.h
@@ -190,7 +190,8 @@ public:
/* reads from the device till reaching a msg that should be sent to the client,
* or till the reading fails */
- virtual RedPipeItem* read_one_msg_from_device() = 0;
+ virtual RedPipeItemPtr read_one_msg_from_device() = 0;
+
/* After this call, the message is unreferenced.
* Can be NULL. */
virtual void send_msg_to_client(RedPipeItem *msg, RedCharDeviceClientOpaque *client) {};
diff --git a/server/cursor-channel.cpp b/server/cursor-channel.cpp
index 2dd0a4be..f78dbba2 100644
--- a/server/cursor-channel.cpp
+++ b/server/cursor-channel.cpp
@@ -191,17 +191,16 @@ cursor_channel_new(RedsState *server, int id,
void CursorChannel::process_cmd(RedCursorCmd *cursor_cmd)
{
- RedCursorPipeItem *cursor_pipe_item;
bool cursor_show = false;
spice_return_if_fail(cursor_cmd);
- cursor_pipe_item = new RedCursorPipeItem(cursor_cmd);
+ auto cursor_pipe_item = red::make_shared<RedCursorPipeItem>(cursor_cmd);
switch (cursor_cmd->type) {
case QXL_CURSOR_SET:
cursor_visible = !!cursor_cmd->u.set.visible;
- cursor_channel_set_item(this, cursor_pipe_item);
+ cursor_channel_set_item(this, cursor_pipe_item.get());
break;
case QXL_CURSOR_MOVE:
cursor_show = !cursor_visible;
@@ -217,7 +216,6 @@ void CursorChannel::process_cmd(RedCursorCmd *cursor_cmd)
break;
default:
spice_warning("invalid cursor command %u", cursor_cmd->type);
- red_pipe_item_unref(cursor_pipe_item);
return;
}
@@ -225,9 +223,7 @@ void CursorChannel::process_cmd(RedCursorCmd *cursor_cmd)
(mouse_mode == SPICE_MOUSE_MODE_SERVER
|| cursor_cmd->type != QXL_CURSOR_MOVE
|| cursor_show)) {
- pipes_add(cursor_pipe_item);
- } else {
- red_pipe_item_unref(cursor_pipe_item);
+ pipes_add(std::move(cursor_pipe_item));
}
}
diff --git a/server/dcc.cpp b/server/dcc.cpp
index d16da328..126598a0 100644
--- a/server/dcc.cpp
+++ b/server/dcc.cpp
@@ -166,7 +166,6 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id)
{
DisplayChannel *display;
RedSurface *surface;
- RedSurfaceCreateItem *create;
uint32_t flags;
if (!dcc) {
@@ -182,11 +181,11 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id)
return;
}
surface = &display->priv->surfaces[surface_id];
- create = new RedSurfaceCreateItem(surface_id, surface->context.width,
- surface->context.height,
- surface->context.format, flags);
+ auto create = red::make_shared<RedSurfaceCreateItem>(surface_id, surface->context.width,
+ surface->context.height,
+ surface->context.format, flags);
dcc->priv->surface_client_created[surface_id] = TRUE;
- dcc->pipe_add(create);
+ dcc->pipe_add(std::move(create));
}
RedImageItem::RedImageItem():
@@ -203,7 +202,6 @@ dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id,
DisplayChannel *display = DCC_TO_DC(dcc);
RedSurface *surface = &display->priv->surfaces[surface_id];
SpiceCanvas *canvas = surface->context.canvas;
- RedImageItem *item;
int stride;
int width;
int height;
@@ -217,7 +215,7 @@ dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id,
bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
stride = width * bpp;
- item = new (height * stride) RedImageItem();
+ red::shared_ptr<RedImageItem> item(new (height * stride) RedImageItem());
item->surface_id = surface_id;
item->image_format =
@@ -246,9 +244,9 @@ dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id,
}
if (pipe_item_pos != dcc->get_pipe().end()) {
- dcc->pipe_add_after_pos(item, pipe_item_pos);
+ dcc->pipe_add_after_pos(std::move(item), pipe_item_pos);
} else {
- dcc->pipe_add(item);
+ dcc->pipe_add(std::move(item));
}
}
@@ -315,41 +313,39 @@ RedDrawablePipeItem::~RedDrawablePipeItem()
drawable_unref(drawable);
}
-static RedDrawablePipeItem *red_drawable_pipe_item_new(DisplayChannelClient *dcc,
- Drawable *drawable)
+static red::shared_ptr<RedDrawablePipeItem>
+red_drawable_pipe_item_new(DisplayChannelClient *dcc, Drawable *drawable)
{
- RedDrawablePipeItem *dpi;
-
- dpi = new RedDrawablePipeItem;
+ auto dpi = red::make_shared<RedDrawablePipeItem>();
dpi->drawable = drawable;
dpi->dcc = dcc;
- drawable->pipes = g_list_prepend(drawable->pipes, dpi);
+ drawable->pipes = g_list_prepend(drawable->pipes, dpi.get());
drawable->refs++;
return dpi;
}
void dcc_prepend_drawable(DisplayChannelClient *dcc, Drawable *drawable)
{
- RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable);
+ auto dpi = red_drawable_pipe_item_new(dcc, drawable);
add_drawable_surface_images(dcc, drawable);
- dcc->pipe_add(dpi);
+ dcc->pipe_add(std::move(dpi));
}
void dcc_append_drawable(DisplayChannelClient *dcc, Drawable *drawable)
{
- RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable);
+ auto dpi = red_drawable_pipe_item_new(dcc, drawable);
add_drawable_surface_images(dcc, drawable);
- dcc->pipe_add_tail(dpi);
+ dcc->pipe_add_tail(std::move(dpi));
}
void dcc_add_drawable_after(DisplayChannelClient *dcc, Drawable *drawable, RedPipeItem *pos)
{
- RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable);
+ auto dpi = red_drawable_pipe_item_new(dcc, drawable);
add_drawable_surface_images(dcc, drawable);
- dcc->pipe_add_after(dpi, pos);
+ dcc->pipe_add_after(std::move(dpi), pos);
}
static void dcc_init_stream_agents(DisplayChannelClient *dcc)
@@ -491,9 +487,9 @@ static void dcc_stop(DisplayChannelClient *dcc)
void dcc_video_stream_agent_clip(DisplayChannelClient* dcc, VideoStreamAgent *agent)
{
- VideoStreamClipItem *item = video_stream_clip_item_new(agent);
+ auto item = video_stream_clip_item_new(agent);
- dcc->pipe_add(item);
+ dcc->pipe_add(std::move(item));
}
RedMonitorsConfigItem::~RedMonitorsConfigItem()
@@ -510,7 +506,6 @@ void dcc_push_monitors_config(DisplayChannelClient *dcc)
{
DisplayChannel *dc = DCC_TO_DC(dcc);
MonitorsConfig *monitors_config = dc->priv->monitors_config;
- RedMonitorsConfigItem *mci;
if (monitors_config == NULL) {
spice_warning("monitors_config is NULL");
@@ -521,8 +516,8 @@ void dcc_push_monitors_config(DisplayChannelClient *dcc)
return;
}
- mci = new RedMonitorsConfigItem(monitors_config);
- dcc->pipe_add(mci);
+ auto mci = red::make_shared<RedMonitorsConfigItem>(monitors_config);
+ dcc->pipe_add(std::move(mci));
}
RedSurfaceDestroyItem::RedSurfaceDestroyItem(uint32_t surface_id)
@@ -530,7 +525,7 @@ RedSurfaceDestroyItem::RedSurfaceDestroyItem(uint32_t surface_id)
surface_destroy.surface_id = surface_id;
}
-RedPipeItem *dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num)
+RedPipeItemPtr dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num)
{
/* FIXME: on !unix peer, start streaming with a video codec */
if (!red_stream_is_plain_unix(rcc->get_stream()) ||
@@ -538,30 +533,29 @@ RedPipeItem *dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num)
red_channel_warning(rcc->get_channel(),
"FIXME: client does not support GL scanout");
rcc->disconnect();
- return NULL;
+ return RedPipeItemPtr();
}
- return new RedGlScanoutUnixItem(RED_PIPE_ITEM_TYPE_GL_SCANOUT);
+ return red::make_shared<RedGlScanoutUnixItem>(RED_PIPE_ITEM_TYPE_GL_SCANOUT);
}
XXX_CAST(RedChannelClient, DisplayChannelClient, DISPLAY_CHANNEL_CLIENT);
-RedPipeItem *dcc_gl_draw_item_new(RedChannelClient *rcc, void *data, int num)
+RedPipeItemPtr dcc_gl_draw_item_new(RedChannelClient *rcc, void *data, int num)
{
DisplayChannelClient *dcc = DISPLAY_CHANNEL_CLIENT(rcc);
const SpiceMsgDisplayGlDraw *draw = (const SpiceMsgDisplayGlDraw *) data;
- RedGlDrawItem *item;
if (!red_stream_is_plain_unix(rcc->get_stream()) ||
!rcc->test_remote_cap(SPICE_DISPLAY_CAP_GL_SCANOUT)) {
red_channel_warning(rcc->get_channel(),
"FIXME: client does not support GL scanout");
rcc->disconnect();
- return NULL;
+ return RedPipeItemPtr();
}
dcc->priv->gl_draw_ongoing = TRUE;
- item = new RedGlDrawItem(RED_PIPE_ITEM_TYPE_GL_DRAW);
+ auto item = red::make_shared<RedGlDrawItem>(RED_PIPE_ITEM_TYPE_GL_DRAW);
item->draw = *draw;
return item;
@@ -570,7 +564,6 @@ RedPipeItem *dcc_gl_draw_item_new(RedChannelClient *rcc, void *data, int num)
void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id)
{
DisplayChannel *display;
- RedSurfaceDestroyItem *destroy;
if (!dcc) {
return;
@@ -584,8 +577,8 @@ void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id)
}
dcc->priv->surface_client_created[surface_id] = FALSE;
- destroy = new RedSurfaceDestroyItem(surface_id);
- dcc->pipe_add(destroy);
+ auto destroy = red::make_shared<RedSurfaceDestroyItem>(surface_id);
+ dcc->pipe_add(std::move(destroy));
}
#define MIN_DIMENSION_TO_QUIC 3
diff --git a/server/dcc.h b/server/dcc.h
index 002da283..696f66af 100644
--- a/server/dcc.h
+++ b/server/dcc.h
@@ -175,10 +175,6 @@ bool dcc_clear_surface_drawables_from_pipe (DisplayCha
int wait_if_used);
bool dcc_drawable_is_in_pipe (DisplayChannelClient *dcc,
Drawable *drawable);
-RedPipeItem * dcc_gl_scanout_item_new (RedChannelClient *rcc,
- void *data, int num);
-RedPipeItem * dcc_gl_draw_item_new (RedChannelClient *rcc,
- void *data, int num);
int dcc_compress_image (DisplayChannelClient *dcc,
SpiceImage *dest, SpiceBitmap *src, Drawable *drawable,
@@ -188,6 +184,8 @@ int dcc_compress_image (DisplayCha
void dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id,
SpiceRect *area, RedChannelClient::Pipe::iterator pipe_item_pos,
int can_lossy);
+RedPipeItemPtr dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num);
+RedPipeItemPtr dcc_gl_draw_item_new(RedChannelClient *rcc, void *data, int num);
VideoStreamAgent *dcc_get_video_stream_agent(DisplayChannelClient *dcc, int stream_id);
ImageEncoders *dcc_get_encoders(DisplayChannelClient *dcc);
spice_wan_compression_t dcc_get_jpeg_state (DisplayChannelClient *dcc);
diff --git a/server/inputs-channel.cpp b/server/inputs-channel.cpp
index b9df9d1a..f22421f3 100644
--- a/server/inputs-channel.cpp
+++ b/server/inputs-channel.cpp
@@ -436,7 +436,7 @@ RedInputsInitPipeItem::RedInputsInitPipeItem(uint8_t init_modifiers):
void InputsChannelClient::pipe_add_init()
{
auto modifiers = kbd_get_leds(get_channel()->keyboard);
- pipe_add_push(new RedInputsInitPipeItem(modifiers));
+ pipe_add_push(red::make_shared<RedInputsInitPipeItem>(modifiers));
}
void InputsChannel::on_connect(RedClient *client, RedStream *stream, int migration,
@@ -461,7 +461,7 @@ void InputsChannel::push_keyboard_modifiers()
if (!is_connected() || src_during_migrate) {
return;
}
- pipes_add(new RedKeyModifiersPipeItem(modifiers));
+ pipes_add(red::make_shared<RedKeyModifiersPipeItem>(modifiers));
}
SPICE_GNUC_VISIBLE int spice_server_kbd_leds(SpiceKbdInstance *sin, int leds)
diff --git a/server/main-channel-client.cpp b/server/main-channel-client.cpp
index eb82614c..32730b4c 100644
--- a/server/main-channel-client.cpp
+++ b/server/main-channel-client.cpp
@@ -142,9 +142,9 @@ void MainChannelClient::on_disconnect()
static void main_channel_client_push_ping(MainChannelClient *mcc, int size);
-static RedPipeItem *main_notify_item_new(const char *msg, int num)
+static RedPipeItemPtr main_notify_item_new(const char *msg, int num)
{
- RedNotifyPipeItem *item = new RedNotifyPipeItem();
+ auto item = red::make_shared<RedNotifyPipeItem>();
item->msg.reset(g_strdup(msg));
return item;
@@ -169,9 +169,9 @@ void MainChannelClient::start_net_test(int test_rate)
main_channel_client_push_ping(this, NET_TEST_BYTES);
}
-static RedPipeItem *red_ping_item_new(int size)
+static RedPipeItemPtr red_ping_item_new(int size)
{
- RedPingPipeItem *item = new RedPingPipeItem();
+ auto item = red::make_shared<RedPingPipeItem>();
item->size = size;
return item;
@@ -179,13 +179,13 @@ static RedPipeItem *red_ping_item_new(int size)
static void main_channel_client_push_ping(MainChannelClient *mcc, int size)
{
- RedPipeItem *item = red_ping_item_new(size);
- mcc->pipe_add_push(item);
+ auto item = red_ping_item_new(size);
+ mcc->pipe_add_push(std::move(item));
}
-static RedPipeItem *main_agent_tokens_item_new(uint32_t num_tokens)
+static RedPipeItemPtr main_agent_tokens_item_new(uint32_t num_tokens)
{
- RedTokensPipeItem *item = new RedTokensPipeItem();
+ auto item = red::make_shared<RedTokensPipeItem>();
item->tokens = num_tokens;
return item;
@@ -194,24 +194,25 @@ static RedPipeItem *main_agent_tokens_item_new(uint32_t num_tokens)
void MainChannelClient::push_agent_tokens(uint32_t num_tokens)
{
- RedPipeItem *item = main_agent_tokens_item_new(num_tokens);
+ auto item = main_agent_tokens_item_new(num_tokens);
- pipe_add_push(item);
+ pipe_add_push(std::move(item));
}
-void MainChannelClient::push_agent_data(RedAgentDataPipeItem *item)
+void MainChannelClient::push_agent_data(red::shared_ptr<RedAgentDataPipeItem>&& item)
{
- pipe_add_push(item);
+ pipe_add_push(std::move(item));
}
-static RedPipeItem *main_init_item_new(int connection_id,
- int display_channels_hint,
- SpiceMouseMode current_mouse_mode,
- int is_client_mouse_allowed,
- int multi_media_time,
- int ram_hint)
+static RedPipeItemPtr
+main_init_item_new(int connection_id,
+ int display_channels_hint,
+ SpiceMouseMode current_mouse_mode,
+ int is_client_mouse_allowed,
+ int multi_media_time,
+ int ram_hint)
{
- RedInitPipeItem *item = new RedInitPipeItem();
+ auto item = red::make_shared<RedInitPipeItem>();
item->connection_id = connection_id;
item->display_channels_hint = display_channels_hint;
@@ -227,37 +228,33 @@ void MainChannelClient::push_init(int display_channels_hint,
int is_client_mouse_allowed,
int multi_media_time, int ram_hint)
{
- RedPipeItem *item;
-
- item = main_init_item_new(priv->connection_id, display_channels_hint,
- current_mouse_mode, is_client_mouse_allowed,
- multi_media_time, ram_hint);
- pipe_add_push(item);
+ auto item = main_init_item_new(priv->connection_id, display_channels_hint,
+ current_mouse_mode, is_client_mouse_allowed,
+ multi_media_time, ram_hint);
+ pipe_add_push(std::move(item));
}
-static RedPipeItem *main_name_item_new(const char *name)
+static RedPipeItemPtr main_name_item_new(const char *name)
{
RedNamePipeItem *item = new (strlen(name) + 1) RedNamePipeItem();
item->msg.name_len = strlen(name) + 1;
memcpy(&item->msg.name, name, item->msg.name_len);
- return item;
+ return RedPipeItemPtr(item);
}
void MainChannelClient::push_name(const char *name)
{
- RedPipeItem *item;
-
if (!test_remote_cap(SPICE_MAIN_CAP_NAME_AND_UUID))
return;
- item = main_name_item_new(name);
- pipe_add_push(item);
+ auto item = main_name_item_new(name);
+ pipe_add_push(std::move(item));
}
-static RedPipeItem *main_uuid_item_new(const uint8_t uuid[16])
+static RedPipeItemPtr main_uuid_item_new(const uint8_t uuid[16])
{
- RedUuidPipeItem *item = new RedUuidPipeItem();
+ auto item = red::make_shared<RedUuidPipeItem>();
memcpy(item->msg.uuid, uuid, sizeof(item->msg.uuid));
@@ -266,44 +263,41 @@ static RedPipeItem *main_uuid_item_new(const uint8_t uuid[16])
void MainChannelClient::push_uuid(const uint8_t uuid[16])
{
- RedPipeItem *item;
-
if (!test_remote_cap(SPICE_MAIN_CAP_NAME_AND_UUID))
return;
- item = main_uuid_item_new(uuid);
- pipe_add_push(item);
+ auto item = main_uuid_item_new(uuid);
+ pipe_add_push(std::move(item));
}
void MainChannelClient::push_notify(const char *msg)
{
- RedPipeItem *item = main_notify_item_new(msg, 1);
- pipe_add_push(item);
+ auto item = main_notify_item_new(msg, 1);
+ pipe_add_push(std::move(item));
}
-RedPipeItem *main_mouse_mode_item_new(SpiceMouseMode current_mode, int is_client_mouse_allowed)
+RedPipeItemPtr
+main_mouse_mode_item_new(SpiceMouseMode current_mode, int is_client_mouse_allowed)
{
- RedMouseModePipeItem *item = new RedMouseModePipeItem();
+ auto item = red::make_shared<RedMouseModePipeItem>();
item->current_mode = current_mode;
item->is_client_mouse_allowed = is_client_mouse_allowed;
return item;
}
-RedPipeItem *main_multi_media_time_item_new(uint32_t mm_time)
+RedPipeItemPtr
+main_multi_media_time_item_new(uint32_t mm_time)
{
- RedMultiMediaTimePipeItem *item;
-
- item = new RedMultiMediaTimePipeItem();
+ auto item = red::make_shared<RedMultiMediaTimePipeItem>();
item->time = mm_time;
return item;
}
-RedPipeItem *registered_channel_item_new(RedChannel *channel)
+RedPipeItemPtr
+registered_channel_item_new(RedChannel *channel)
{
- RedRegisteredChannelPipeItem *item;
-
- item = new RedRegisteredChannelPipeItem();
+ auto item = red::make_shared<RedRegisteredChannelPipeItem>();
item->channel_type = channel->type();
item->channel_id = channel->id();
diff --git a/server/main-channel-client.h b/server/main-channel-client.h
index c7973d29..56401a8b 100644
--- a/server/main-channel-client.h
+++ b/server/main-channel-client.h
@@ -38,7 +38,7 @@ class MainChannelClient final: public RedChannelClient
{
public:
void push_agent_tokens(uint32_t num_tokens);
- void push_agent_data(RedAgentDataPipeItem *item);
+ void push_agent_data(red::shared_ptr<RedAgentDataPipeItem>&& item);
// TODO: huge. Consider making a reds_* interface for these functions
// and calling from main.
void push_init(int display_channels_hint, SpiceMouseMode current_mouse_mode,
@@ -120,11 +120,11 @@ struct RedAgentDataPipeItem: public RedPipeItemNum<RED_PIPE_ITEM_TYPE_MAIN_AGENT
uint8_t data[SPICE_AGENT_MAX_DATA_SIZE];
};
-RedPipeItem *main_mouse_mode_item_new(SpiceMouseMode current_mode, int is_client_mouse_allowed);
+RedPipeItemPtr main_mouse_mode_item_new(SpiceMouseMode current_mode, int is_client_mouse_allowed);
-RedPipeItem *main_multi_media_time_item_new(uint32_t mm_time);
+RedPipeItemPtr main_multi_media_time_item_new(uint32_t mm_time);
-RedPipeItem *registered_channel_item_new(RedChannel *channel);
+RedPipeItemPtr registered_channel_item_new(RedChannel *channel);
#include "pop-visibility.h"
diff --git a/server/red-channel-client.cpp b/server/red-channel-client.cpp
index e8827911..850047a5 100644
--- a/server/red-channel-client.cpp
+++ b/server/red-channel-client.cpp
@@ -174,7 +174,7 @@ struct RedChannelClientPrivate
RedStatCounter out_bytes;
inline RedPipeItemPtr pipe_item_get();
- inline bool pipe_remove(RedPipeItem *item);
+ inline void pipe_remove(RedPipeItem *item);
void handle_pong(SpiceMsgPing *ping);
inline void set_message_serial(uint64_t serial);
void pipe_clear();
@@ -514,7 +514,6 @@ void RedChannelClient::send_any_item(RedPipeItem *item)
send_item(item);
break;
}
- red_pipe_item_unref(item);
}
inline void RedChannelClientPrivate::restore_main_sender()
@@ -565,14 +564,12 @@ find_pipe_item(RedChannelClient::Pipe &pipe, const RedPipeItem *item)
});
}
-bool RedChannelClientPrivate::pipe_remove(RedPipeItem *item)
+void RedChannelClientPrivate::pipe_remove(RedPipeItem *item)
{
auto i = find_pipe_item(pipe, item);
if (i != pipe.end()) {
pipe.erase(i);
- return true;
}
- return false;
}
bool RedChannelClient::test_remote_common_cap(uint32_t cap) const
@@ -1137,8 +1134,6 @@ inline RedPipeItemPtr RedChannelClientPrivate::pipe_item_get()
void RedChannelClient::push()
{
- RedPipeItemPtr pipe_item;
-
if (priv->during_send) {
return;
}
@@ -1155,7 +1150,7 @@ void RedChannelClient::push()
"ERROR: an item waiting to be sent and not blocked");
}
- while ((pipe_item = priv->pipe_item_get())) {
+ while (auto pipe_item = priv->pipe_item_get()) {
send_any_item(pipe_item.get());
}
/* prepare_pipe_add() will reenable WRITE events when the priv->pipe is empty
@@ -1370,7 +1365,6 @@ inline bool RedChannelClient::prepare_pipe_add(RedPipeItem *item)
spice_assert(item);
if (SPICE_UNLIKELY(!is_connected())) {
spice_debug("rcc is disconnected %p", this);
- red_pipe_item_unref(item);
return false;
}
if (priv->pipe.empty()) {
@@ -1379,50 +1373,50 @@ inline bool RedChannelClient::prepare_pipe_add(RedPipeItem *item)
return true;
}
-void RedChannelClient::pipe_add(RedPipeItem *item)
+void RedChannelClient::pipe_add(RedPipeItemPtr&& item)
{
- if (!prepare_pipe_add(item)) {
+ if (!prepare_pipe_add(item.get())) {
return;
}
- priv->pipe.push_front(RedPipeItemPtr(item));
+ priv->pipe.push_front(std::move(item));
}
-void RedChannelClient::pipe_add_push(RedPipeItem *item)
+void RedChannelClient::pipe_add_push(RedPipeItemPtr&& item)
{
- pipe_add(item);
+ pipe_add(std::move(item));
push();
}
-void RedChannelClient::pipe_add_after_pos(RedPipeItem *item,
+void RedChannelClient::pipe_add_after_pos(RedPipeItemPtr&& item,
Pipe::iterator pipe_item_pos)
{
spice_assert(pipe_item_pos != priv->pipe.end());
- if (!prepare_pipe_add(item)) {
+ if (!prepare_pipe_add(item.get())) {
return;
}
++pipe_item_pos;
- priv->pipe.insert(pipe_item_pos, RedPipeItemPtr(item));
+ priv->pipe.insert(pipe_item_pos, std::move(item));
}
void
-RedChannelClient::pipe_add_before_pos(RedPipeItem *item, Pipe::iterator pipe_item_pos)
+RedChannelClient::pipe_add_before_pos(RedPipeItemPtr&& item, Pipe::iterator pipe_item_pos)
{
spice_assert(pipe_item_pos != priv->pipe.end());
- if (!prepare_pipe_add(item)) {
+ if (!prepare_pipe_add(item.get())) {
return;
}
- priv->pipe.insert(pipe_item_pos, RedPipeItemPtr(item));
+ priv->pipe.insert(pipe_item_pos, std::move(item));
}
-void RedChannelClient::pipe_add_after(RedPipeItem *item, RedPipeItem *pos)
+void RedChannelClient::pipe_add_after(RedPipeItemPtr&& item, RedPipeItem *pos)
{
spice_assert(pos);
auto prev = find_pipe_item(priv->pipe, pos);
g_return_if_fail(prev != priv->pipe.end());
- pipe_add_after_pos(item, prev);
+ pipe_add_after_pos(std::move(item), prev);
}
int RedChannelClient::pipe_item_is_linked(RedPipeItem *item)
@@ -1430,24 +1424,24 @@ int RedChannelClient::pipe_item_is_linked(RedPipeItem *item)
return find_pipe_item(priv->pipe, item) != priv->pipe.end();
}
-void RedChannelClient::pipe_add_tail(RedPipeItem *item)
+void RedChannelClient::pipe_add_tail(RedPipeItemPtr&& item)
{
- if (!prepare_pipe_add(item)) {
+ if (!prepare_pipe_add(item.get())) {
return;
}
- priv->pipe.push_back(RedPipeItemPtr(item));
+ priv->pipe.push_back(std::move(item));
}
void RedChannelClient::pipe_add_type(int pipe_item_type)
{
- RedPipeItem *item = new RedPipeItem(pipe_item_type);
+ auto item = red::make_shared<RedPipeItem>(pipe_item_type);
- pipe_add(item);
+ pipe_add(std::move(item));
}
-RedPipeItem *RedChannelClient::new_empty_msg(int msg_type)
+RedPipeItemPtr RedChannelClient::new_empty_msg(int msg_type)
{
- RedEmptyMsgPipeItem *item = new RedEmptyMsgPipeItem();
+ auto item = red::make_shared<RedEmptyMsgPipeItem>();
item->msg = msg_type;
return item;
@@ -1586,7 +1580,7 @@ bool RedChannelClient::wait_pipe_item_sent(Pipe::iterator item_pos, int64_t time
auto mark_item = red::make_shared<MarkerPipeItem>();
mark_item->item_sent = false;
- pipe_add_before_pos(mark_item.get(), item_pos);
+ pipe_add_before_pos(RedPipeItemPtr(mark_item), item_pos);
for (;;) {
receive();
@@ -1643,9 +1637,7 @@ bool RedChannelClient::no_item_being_sent() const
void RedChannelClient::pipe_remove_and_release(RedPipeItem *item)
{
- if (priv->pipe_remove(item)) {
- red_pipe_item_unref(item);
- }
+ priv->pipe_remove(item);
}
/* client mutex should be locked before this call */
diff --git a/server/red-channel-client.h b/server/red-channel-client.h
index 69099882..4f8c7b0d 100644
--- a/server/red-channel-client.h
+++ b/server/red-channel-client.h
@@ -85,16 +85,17 @@ protected:
public:
typedef std::list<RedPipeItemPtr, red::Mallocator<RedPipeItemPtr>> Pipe;
- void pipe_add_push(RedPipeItem *item);
- void pipe_add(RedPipeItem *item);
- void pipe_add_after(RedPipeItem *item, RedPipeItem *pos);
- void pipe_add_after_pos(RedPipeItem *item, RedChannelClient::Pipe::iterator pos);
+ void pipe_add_push(RedPipeItemPtr&& item);
+ void pipe_add(RedPipeItemPtr&& item);
+ void pipe_add_after(RedPipeItemPtr&& item, RedPipeItem *pos);
+ void pipe_add_after_pos(RedPipeItemPtr&& item,
+ RedChannelClient::Pipe::iterator pos);
int pipe_item_is_linked(RedPipeItem *item);
void pipe_remove_and_release(RedPipeItem *item);
- void pipe_add_tail(RedPipeItem *item);
+ void pipe_add_tail(RedPipeItemPtr&& item);
/* for types that use this routine -> the pipe item should be freed */
void pipe_add_type(int pipe_item_type);
- static RedPipeItem *new_empty_msg(int msg_type);
+ static RedPipeItemPtr new_empty_msg(int msg_type);
void pipe_add_empty_msg(int msg_type);
gboolean pipe_is_empty();
uint32_t get_pipe_size();
@@ -184,7 +185,7 @@ private:
virtual void handle_migrate_flush_mark();
void handle_migrate_data_early(uint32_t size, void *message);
inline bool prepare_pipe_add(RedPipeItem *item);
- void pipe_add_before_pos(RedPipeItem *item, RedChannelClient::Pipe::iterator pipe_item_pos);
+ void pipe_add_before_pos(RedPipeItemPtr&& item, RedChannelClient::Pipe::iterator pipe_item_pos);
void send_set_ack();
void send_migrate();
void send_empty_msg(RedPipeItem *base);
diff --git a/server/red-channel.cpp b/server/red-channel.cpp
index bedb323a..dc577695 100644
--- a/server/red-channel.cpp
+++ b/server/red-channel.cpp
@@ -266,23 +266,20 @@ void RedChannel::push()
red_channel_foreach_client(this, &RedChannelClient::push);
}
-void RedChannel::pipes_add(RedPipeItem *item)
+void RedChannel::pipes_add(RedPipeItemPtr&& item)
{
RedChannelClient *rcc;
FOREACH_CLIENT(this, rcc) {
- red_pipe_item_ref(item);
- rcc->pipe_add(item);
+ rcc->pipe_add(RedPipeItemPtr(item));
}
-
- red_pipe_item_unref(item);
}
void RedChannel::pipes_add_type(int pipe_item_type)
{
- RedPipeItem *item = new RedPipeItem(pipe_item_type);
+ auto item = red::make_shared<RedPipeItem>(pipe_item_type);
- pipes_add(item);
+ pipes_add(std::move(item));
}
void RedChannel::pipes_add_empty_msg(int msg_type)
@@ -437,15 +434,14 @@ static bool red_channel_no_item_being_sent(RedChannel *channel)
int RedChannel::pipes_new_add(new_pipe_item_t creator, void *data)
{
RedChannelClient *rcc;
- RedPipeItem *item;
int num = 0, n = 0;
spice_assert(creator != NULL);
FOREACH_CLIENT(this, rcc) {
- item = (*creator)(rcc, data, num++);
+ auto item = (*creator)(rcc, data, num++);
if (item) {
- rcc->pipe_add(item);
+ rcc->pipe_add(std::move(item));
n++;
}
}
diff --git a/server/red-channel.h b/server/red-channel.h
index af288a82..60fef188 100644
--- a/server/red-channel.h
+++ b/server/red-channel.h
@@ -109,7 +109,7 @@ struct RedChannel: public red::shared_ptr_counted
bool test_remote_cap(uint32_t cap);
// helper to push a new item to all channels
- typedef RedPipeItem *(*new_pipe_item_t)(RedChannelClient *rcc, void *data, int num);
+ typedef RedPipeItemPtr (*new_pipe_item_t)(RedChannelClient *rcc, void *data, int num);
int pipes_new_add(new_pipe_item_t creator, void *data);
void pipes_add_type(int pipe_item_type);
@@ -120,7 +120,7 @@ struct RedChannel: public red::shared_ptr_counted
* The same item is shared between all clients.
* Function will take ownership of the item.
*/
- void pipes_add(RedPipeItem *item);
+ void pipes_add(RedPipeItemPtr&& item);
/* return TRUE if all of the connected clients to this channel are blocked */
bool all_blocked();
diff --git a/server/red-pipe-item.cpp b/server/red-pipe-item.cpp
index 1aedd700..a871bfef 100644
--- a/server/red-pipe-item.cpp
+++ b/server/red-pipe-item.cpp
@@ -23,8 +23,6 @@
RedPipeItem::RedPipeItem(int init_type):
type(init_type)
{
- // compatibility with no shared_ptr reference counting
- shared_ptr_add_ref(this);
}
RedPipeItem *red_pipe_item_ref(RedPipeItem *item)
diff --git a/server/red-stream-device.cpp b/server/red-stream-device.cpp
index d21c6e77..983e2b94 100644
--- a/server/red-stream-device.cpp
+++ b/server/red-stream-device.cpp
@@ -158,12 +158,12 @@ StreamDevice::partial_read()
return false;
}
-RedPipeItem* StreamDevice::read_one_msg_from_device()
+RedPipeItemPtr StreamDevice::read_one_msg_from_device()
{
while (partial_read()) {
continue;
}
- return NULL;
+ return RedPipeItemPtr();
}
bool
diff --git a/server/red-stream-device.h b/server/red-stream-device.h
index c10e4beb..bf657878 100644
--- a/server/red-stream-device.h
+++ b/server/red-stream-device.h
@@ -90,7 +90,7 @@ private:
StreamDeviceDisplayInfo device_display_info;
private:
- virtual RedPipeItem* read_one_msg_from_device() override;
+ virtual RedPipeItemPtr read_one_msg_from_device() override;
virtual void remove_client(RedCharDeviceClientOpaque *client) override;
virtual void port_event(uint8_t event) override;
diff --git a/server/reds.cpp b/server/reds.cpp
index 94a0d703..fb465c81 100644
--- a/server/reds.cpp
+++ b/server/reds.cpp
@@ -182,7 +182,7 @@ struct RedCharDeviceVDIPortPrivate {
uint32_t message_receive_len;
uint8_t *receive_pos;
uint32_t receive_len;
- RedVDIReadBuf *current_read_buf;
+ red::shared_ptr<RedVDIReadBuf> current_read_buf;
AgentMsgFilter read_filter;
VDIChunkHeader vdi_chunk_header;
@@ -210,7 +210,7 @@ struct RedCharDeviceVDIPort: public RedCharDevice
RedCharDeviceVDIPort();
~RedCharDeviceVDIPort();
- virtual RedPipeItem* read_one_msg_from_device() override;
+ virtual RedPipeItemPtr read_one_msg_from_device() override;
virtual void send_msg_to_client(RedPipeItem *msg, RedCharDeviceClientOpaque *opaque) override;
virtual void send_tokens_to_client(RedCharDeviceClientOpaque *opaque, uint32_t tokens) override;
virtual void remove_client(RedCharDeviceClientOpaque *opaque);
@@ -235,7 +235,7 @@ static void reds_set_mouse_mode(RedsState *reds, SpiceMouseMode mode);
static uint32_t reds_qxl_ram_size(RedsState *reds);
static int calc_compression_level(RedsState *reds);
-static RedVDIReadBuf *vdi_port_get_read_buf(RedCharDeviceVDIPort *dev);
+static red::shared_ptr<RedVDIReadBuf> vdi_port_get_read_buf(RedCharDeviceVDIPort *dev);
static ChannelSecurityOptions *reds_find_channel_security(RedsState *reds, int id)
{
@@ -401,10 +401,8 @@ static void reds_reset_vdp(RedsState *reds)
dev->priv->receive_pos = (uint8_t *)&dev->priv->vdi_chunk_header;
dev->priv->receive_len = sizeof(dev->priv->vdi_chunk_header);
dev->priv->message_receive_len = 0;
- if (dev->priv->current_read_buf) {
- red_pipe_item_unref(dev->priv->current_read_buf);
- dev->priv->current_read_buf = NULL;
- }
+ dev->priv->current_read_buf.reset();
+
/* Reset read filter to start with clean state when the agent reconnects */
agent_msg_filter_init(&dev->priv->read_filter, reds->config->agent_copypaste,
reds->config->agent_file_xfer,
@@ -659,11 +657,11 @@ static void reds_agent_remove(RedsState *reds)
other values can be discarded
*/
static AgentMsgFilterResult vdi_port_read_buf_process(RedCharDeviceVDIPort *dev,
- RedVDIReadBuf *buf)
+ RedVDIReadBuf& buf)
{
switch (dev->priv->vdi_chunk_header.port) {
case VDP_CLIENT_PORT:
- return agent_msg_filter_process_data(&dev->priv->read_filter, buf->data, buf->len);
+ return agent_msg_filter_process_data(&dev->priv->read_filter, buf.data, buf.len);
case VDP_SERVER_PORT:
return AGENT_MSG_FILTER_DISCARD;
default:
@@ -685,17 +683,17 @@ RedVDIReadBuf::~RedVDIReadBuf()
}
}
-static RedVDIReadBuf *vdi_read_buf_new(RedCharDeviceVDIPort *dev)
+static red::shared_ptr<RedVDIReadBuf> vdi_read_buf_new(RedCharDeviceVDIPort *dev)
{
- RedVDIReadBuf *buf = new RedVDIReadBuf();
+ auto buf = red::make_shared<RedVDIReadBuf>();
buf->dev = dev;
return buf;
}
-static RedVDIReadBuf *vdi_port_get_read_buf(RedCharDeviceVDIPort *dev)
+static red::shared_ptr<RedVDIReadBuf> vdi_port_get_read_buf(RedCharDeviceVDIPort *dev)
{
if (dev->priv->num_read_buf >= REDS_VDI_PORT_NUM_RECEIVE_BUFFS) {
- return NULL;
+ return red::shared_ptr<RedVDIReadBuf>();
}
dev->priv->num_read_buf++;
@@ -731,11 +729,10 @@ static void reds_adjust_agent_capabilities(RedsState *reds, VDAgentMessage *mess
/* reads from the device till completes reading a message that is addressed to the client,
* or otherwise, when reading from the device fails */
-RedPipeItem *
+RedPipeItemPtr
RedCharDeviceVDIPort::read_one_msg_from_device()
{
RedsState *reds;
- RedVDIReadBuf *dispatch_buf;
int n;
reds = get_server();
@@ -744,18 +741,18 @@ RedCharDeviceVDIPort::read_one_msg_from_device()
case VDI_PORT_READ_STATE_READ_HEADER:
n = read(priv->receive_pos, priv->receive_len);
if (!n) {
- return NULL;
+ return RedPipeItemPtr();
}
if ((priv->receive_len -= n)) {
priv->receive_pos += n;
- return NULL;
+ return RedPipeItemPtr();
}
priv->message_receive_len = priv->vdi_chunk_header.size;
priv->read_state = VDI_PORT_READ_STATE_GET_BUFF;
/* fall through */
case VDI_PORT_READ_STATE_GET_BUFF: {
if (!(priv->current_read_buf = vdi_port_get_read_buf(this))) {
- return NULL;
+ return RedPipeItemPtr();
}
priv->receive_pos = priv->current_read_buf->data;
priv->receive_len = MIN(priv->message_receive_len,
@@ -768,14 +765,13 @@ RedCharDeviceVDIPort::read_one_msg_from_device()
case VDI_PORT_READ_STATE_READ_DATA: {
n = read(priv->receive_pos, priv->receive_len);
if (!n) {
- return NULL;
+ return RedPipeItemPtr();
}
if ((priv->receive_len -= n)) {
priv->receive_pos += n;
break;
}
- dispatch_buf = priv->current_read_buf;
- priv->current_read_buf = NULL;
+ auto dispatch_buf = std::move(priv->current_read_buf);
priv->receive_pos = NULL;
if (priv->message_receive_len == 0) {
priv->read_state = VDI_PORT_READ_STATE_READ_HEADER;
@@ -784,7 +780,7 @@ RedCharDeviceVDIPort::read_one_msg_from_device()
} else {
priv->read_state = VDI_PORT_READ_STATE_GET_BUFF;
}
- switch (vdi_port_read_buf_process(this, dispatch_buf)) {
+ switch (vdi_port_read_buf_process(this, *dispatch_buf)) {
case AGENT_MSG_FILTER_OK:
reds_adjust_agent_capabilities(reds, (VDAgentMessage *) dispatch_buf->data);
return dispatch_buf;
@@ -794,12 +790,12 @@ RedCharDeviceVDIPort::read_one_msg_from_device()
case AGENT_MSG_FILTER_MONITORS_CONFIG:
/* fall through */
case AGENT_MSG_FILTER_DISCARD:
- red_pipe_item_unref(dispatch_buf);
+ dispatch_buf.reset();
}
}
} /* END switch */
} /* END while */
- return NULL;
+ return RedPipeItemPtr();
}
void reds_marshall_device_display_info(RedsState *reds, SpiceMarshaller *m)
@@ -893,8 +889,7 @@ void RedCharDeviceVDIPort::send_msg_to_client(RedPipeItem *msg, RedCharDeviceCli
RedClient *client = (RedClient *) opaque;
RedVDIReadBuf *agent_data_buf = static_cast<RedVDIReadBuf*>(msg);
- red_pipe_item_ref(msg);
- client->get_main()->push_agent_data(agent_data_buf);
+ client->get_main()->push_agent_data(red::shared_ptr<RedAgentDataPipeItem>(agent_data_buf));
}
void RedCharDeviceVDIPort::send_tokens_to_client(RedCharDeviceClientOpaque *opaque, uint32_t tokens)
@@ -1242,16 +1237,16 @@ void reds_on_main_channel_migrate(RedsState *reds, MainChannelClient *mcc)
if (agent_dev->priv->read_filter.msg_data_to_read ||
read_data_len > sizeof(VDAgentMessage)) { /* msg header has been read */
- RedVDIReadBuf *read_buf = agent_dev->priv->current_read_buf;
+ red::shared_ptr<RedVDIReadBuf> read_buf = std::move(agent_dev->priv->current_read_buf);
spice_debug("push partial read %u (msg first chunk? %d)", read_data_len,
!agent_dev->priv->read_filter.msg_data_to_read);
read_buf->len = read_data_len;
- switch (vdi_port_read_buf_process(agent_dev, read_buf)) {
+ switch (vdi_port_read_buf_process(agent_dev, *read_buf)) {
case AGENT_MSG_FILTER_OK:
reds_adjust_agent_capabilities(reds, (VDAgentMessage *)read_buf->data);
- mcc->push_agent_data(read_buf);
+ mcc->push_agent_data(std::move(read_buf));
break;
case AGENT_MSG_FILTER_PROTO_ERROR:
reds_agent_remove(reds);
@@ -1259,13 +1254,12 @@ void reds_on_main_channel_migrate(RedsState *reds, MainChannelClient *mcc)
case AGENT_MSG_FILTER_MONITORS_CONFIG:
/* fall through */
case AGENT_MSG_FILTER_DISCARD:
- red_pipe_item_unref(read_buf);
+ read_buf.reset();
}
spice_assert(agent_dev->priv->receive_len);
agent_dev->priv->message_receive_len += agent_dev->priv->receive_len;
agent_dev->priv->read_state = VDI_PORT_READ_STATE_GET_BUFF;
- agent_dev->priv->current_read_buf = NULL;
agent_dev->priv->receive_pos = NULL;
}
}
@@ -1395,7 +1389,7 @@ static int reds_agent_state_restore(RedsState *reds, SpiceMigrateDataMain *mig_d
}
} else {
agent_dev->priv->read_state = VDI_PORT_READ_STATE_GET_BUFF;
- agent_dev->priv->current_read_buf = NULL;
+ agent_dev->priv->current_read_buf.reset();
agent_dev->priv->receive_pos = NULL;
agent_dev->priv->read_filter.msg_data_to_read = mig_data->agent2client.msg_remaining;
agent_dev->priv->read_filter.result = (AgentMsgFilterResult) mig_data->agent2client.msg_filter_result;
@@ -4447,10 +4441,7 @@ RedCharDeviceVDIPort::~RedCharDeviceVDIPort()
{
/* make sure we have no other references to RedVDIReadBuf buffers */
reset();
- if (priv->current_read_buf) {
- red_pipe_item_unref(priv->current_read_buf);
- priv->current_read_buf = NULL;
- }
+ priv->current_read_buf.reset(); // needed to pass the assert below
g_free(priv->mig_data);
spice_extra_assert(priv->num_read_buf == 0);
}
diff --git a/server/smartcard-channel-client.cpp b/server/smartcard-channel-client.cpp
index 051facd1..65c402f3 100644
--- a/server/smartcard-channel-client.cpp
+++ b/server/smartcard-channel-client.cpp
@@ -137,7 +137,7 @@ static void smartcard_channel_client_push_error(RedChannelClient *rcc,
uint32_t reader_id,
VSCErrorCode error)
{
- RedErrorItem *error_item = new RedErrorItem();
+ auto error_item = red::make_shared<RedErrorItem>();
error_item->vheader.reader_id = reader_id;
error_item->vheader.type = VSC_Error;
diff --git a/server/smartcard.cpp b/server/smartcard.cpp
index c33844dd..e76ec033 100644
--- a/server/smartcard.cpp
+++ b/server/smartcard.cpp
@@ -71,7 +71,8 @@ struct RedMsgItem: public RedPipeItemNum<RED_PIPE_ITEM_TYPE_SMARTCARD_DATA> {
red::glib_unique_ptr<VSCMsgHeader> vheader;
};
-static RedMsgItem *smartcard_new_vsc_msg_item(unsigned int reader_id, const VSCMsgHeader *vheader);
+static red::shared_ptr<RedMsgItem>
+smartcard_new_vsc_msg_item(unsigned int reader_id, const VSCMsgHeader *vheader);
static struct Readers {
uint32_t num;
@@ -80,8 +81,8 @@ static struct Readers {
static int smartcard_char_device_add_to_readers(RedsState *reds, SpiceCharDeviceInstance *sin);
-static RedMsgItem *smartcard_char_device_on_message_from_device(
- RedCharDeviceSmartcard *dev, VSCMsgHeader *header);
+static red::shared_ptr<RedMsgItem>
+smartcard_char_device_on_message_from_device(RedCharDeviceSmartcard *dev, VSCMsgHeader *header);
static void smartcard_init(RedsState *reds);
static void smartcard_read_buf_prepare(RedCharDeviceSmartcard *dev, VSCMsgHeader *vheader)
@@ -95,7 +96,7 @@ static void smartcard_read_buf_prepare(RedCharDeviceSmartcard *dev, VSCMsgHeader
}
}
-RedPipeItem*
+RedPipeItemPtr
RedCharDeviceSmartcard::read_one_msg_from_device()
{
RedCharDeviceSmartcard *dev = this;
@@ -104,8 +105,6 @@ RedCharDeviceSmartcard::read_one_msg_from_device()
int actual_length;
while (true) {
- RedMsgItem *msg_to_client;
-
// it's possible we already got a full message from a previous partial
// read. In this case we don't need to read any byte
if (dev->priv->buf_used < sizeof(VSCMsgHeader) ||
@@ -127,22 +126,18 @@ RedCharDeviceSmartcard::read_one_msg_from_device()
if (dev->priv->buf_used - sizeof(VSCMsgHeader) < actual_length) {
continue;
}
- msg_to_client = smartcard_char_device_on_message_from_device(dev, vheader);
+ auto msg_to_client = smartcard_char_device_on_message_from_device(dev, vheader);
remaining = dev->priv->buf_used - sizeof(VSCMsgHeader) - actual_length;
if (remaining > 0) {
memmove(dev->priv->buf, dev->priv->buf_pos - remaining, remaining);
}
dev->priv->buf_pos = dev->priv->buf + remaining;
dev->priv->buf_used = remaining;
- if (msg_to_client) {
- if (dev->priv->scc) {
- dev->priv->scc->pipe_add_push(msg_to_client);
- } else {
- red_pipe_item_unref(msg_to_client);
- }
+ if (msg_to_client && dev->priv->scc) {
+ dev->priv->scc->pipe_add_push(std::move(msg_to_client));
}
}
- return NULL;
+ return RedPipeItemPtr();
}
void RedCharDeviceSmartcard::remove_client(RedCharDeviceClientOpaque *opaque)
@@ -153,15 +148,16 @@ void RedCharDeviceSmartcard::remove_client(RedCharDeviceClientOpaque *opaque)
scc->shutdown();
}
-RedMsgItem *smartcard_char_device_on_message_from_device(RedCharDeviceSmartcard *dev,
- VSCMsgHeader *vheader)
+red::shared_ptr<RedMsgItem>
+smartcard_char_device_on_message_from_device(RedCharDeviceSmartcard *dev,
+ VSCMsgHeader *vheader)
{
vheader->type = ntohl(vheader->type);
vheader->length = ntohl(vheader->length);
vheader->reader_id = ntohl(vheader->reader_id);
if (vheader->type == VSC_Init) {
- return NULL;
+ return red::shared_ptr<RedMsgItem>();
}
/* We pass any VSC_Error right now - might need to ignore some? */
if (dev->priv->reader_id == VSCARD_UNDEFINED_READER_ID) {
@@ -170,7 +166,7 @@ RedMsgItem *smartcard_char_device_on_message_from_device(RedCharDeviceSmartcard
vheader->type);
}
if (dev->priv->scc == NULL) {
- return NULL;
+ return red::shared_ptr<RedMsgItem>();
}
return smartcard_new_vsc_msg_item(dev->priv->reader_id, vheader);
}
@@ -388,9 +384,10 @@ void SmartCardChannelClient::send_item(RedPipeItem *item)
begin_send_message();
}
-static RedMsgItem *smartcard_new_vsc_msg_item(unsigned int reader_id, const VSCMsgHeader *vheader)
+static red::shared_ptr<RedMsgItem>
+smartcard_new_vsc_msg_item(unsigned int reader_id, const VSCMsgHeader *vheader)
{
- RedMsgItem *msg_item = new RedMsgItem();
+ auto msg_item = red::make_shared<RedMsgItem>();
msg_item->vheader.reset((VSCMsgHeader*) g_memdup(vheader, sizeof(*vheader) + vheader->length));
/* We patch the reader_id, since the device only knows about itself, and
diff --git a/server/smartcard.h b/server/smartcard.h
index 242413d7..7ac7cc5a 100644
--- a/server/smartcard.h
+++ b/server/smartcard.h
@@ -34,7 +34,7 @@ public:
protected:
~RedCharDeviceSmartcard();
private:
- RedPipeItem* read_one_msg_from_device() override;
+ RedPipeItemPtr read_one_msg_from_device() override;
void remove_client(RedCharDeviceClientOpaque *client) override;
public: // XXX make private
red::unique_link<RedCharDeviceSmartcardPrivate> priv;
diff --git a/server/sound.cpp b/server/sound.cpp
index 386463e4..a7d7a11f 100644
--- a/server/sound.cpp
+++ b/server/sound.cpp
@@ -618,6 +618,8 @@ static bool playback_send_mode(PlaybackChannelClient *playback_client)
PersistentPipeItem::PersistentPipeItem()
{
+ // force this item to stay alive
+ shared_ptr_add_ref(this);
}
static void snd_send(SndChannelClient * client)
@@ -626,8 +628,8 @@ static void snd_send(SndChannelClient * client)
return;
}
// just append a dummy item and push!
- red_pipe_item_ref(&client->persistent_pipe_item);
- client->pipe_add_push(&client->persistent_pipe_item);
+ RedPipeItemPtr item(&client->persistent_pipe_item);
+ client->pipe_add_push(std::move(item));
}
XXX_CAST(RedChannelClient, PlaybackChannelClient, PLAYBACK_CHANNEL_CLIENT)
diff --git a/server/spicevmc.cpp b/server/spicevmc.cpp
index a290bfbf..c128bc3b 100644
--- a/server/spicevmc.cpp
+++ b/server/spicevmc.cpp
@@ -65,7 +65,7 @@ struct RedCharDeviceSpiceVmc: public RedCharDevice
RedCharDeviceSpiceVmc(SpiceCharDeviceInstance *sin, RedsState *reds, RedVmcChannel *channel);
~RedCharDeviceSpiceVmc();
- virtual RedPipeItem* read_one_msg_from_device() override;
+ virtual RedPipeItemPtr read_one_msg_from_device() override;
virtual void remove_client(RedCharDeviceClientOpaque *opaque) override;
virtual void on_free_self_token() override;
virtual void port_event(uint8_t event) override;
@@ -73,7 +73,7 @@ struct RedCharDeviceSpiceVmc: public RedCharDevice
red::shared_ptr<RedVmcChannel> channel;
};
-static void spicevmc_red_channel_queue_data(RedVmcChannel *channel, RedVmcPipeItem *item);
+static void spicevmc_red_channel_queue_data(RedVmcChannel *channel, red::shared_ptr<RedVmcPipeItem>&& item);
struct RedVmcChannel: public RedChannel
{
@@ -86,7 +86,7 @@ struct RedVmcChannel: public RedChannel
VmcChannelClient *rcc;
RedCharDevice *chardev; /* weak */
SpiceCharDeviceInstance *chardev_sin;
- RedVmcPipeItem *pipe_item;
+ red::shared_ptr<RedVmcPipeItem> pipe_item;
RedCharDeviceWriteBuffer *recv_from_client_buf;
uint8_t port_opened;
uint32_t queued_data;
@@ -162,9 +162,6 @@ RedVmcChannel::RedVmcChannel(RedsState *reds, uint32_t type, uint32_t id):
RedVmcChannel::~RedVmcChannel()
{
RedCharDevice::write_buffer_release(chardev, &recv_from_client_buf);
- if (pipe_item) {
- red_pipe_item_unref(pipe_item);
- }
}
static red::shared_ptr<RedVmcChannel> red_vmc_channel_new(RedsState *reds, uint8_t channel_type)
@@ -204,24 +201,25 @@ struct RedPortEventPipeItem: public RedPipeItemNum<RED_PIPE_ITEM_TYPE_PORT_EVENT
* - a new pipe item with the compressed data in it upon success
*/
#ifdef USE_LZ4
-static RedVmcPipeItem* try_compress_lz4(RedVmcChannel *channel, int n, RedVmcPipeItem *msg_item)
+static red::shared_ptr<RedVmcPipeItem>
+try_compress_lz4(RedVmcChannel *channel, int n, RedVmcPipeItem *msg_item)
{
- RedVmcPipeItem *msg_item_compressed;
+ red::shared_ptr<RedVmcPipeItem> msg_item_compressed;
int compressed_data_count;
if (red_stream_get_family(channel->rcc->get_stream()) == AF_UNIX) {
/* AF_LOCAL - data will not be compressed */
- return NULL;
+ return msg_item_compressed;
}
if (n <= COMPRESS_THRESHOLD) {
/* n <= threshold - data will not be compressed */
- return NULL;
+ return msg_item_compressed;
}
if (!channel->rcc->test_remote_cap(SPICE_SPICEVMC_CAP_DATA_COMPRESS_LZ4)) {
/* Client doesn't have compression cap - data will not be compressed */
- return NULL;
+ return msg_item_compressed;
}
- msg_item_compressed = new RedVmcPipeItem();
+ msg_item_compressed = red::make_shared<RedVmcPipeItem>();
compressed_data_count = LZ4_compress_default((char*)&msg_item->buf,
(char*)&msg_item_compressed->buf,
n,
@@ -233,73 +231,72 @@ static RedVmcPipeItem* try_compress_lz4(RedVmcChannel *channel, int n, RedVmcPip
msg_item_compressed->type = SPICE_DATA_COMPRESSION_TYPE_LZ4;
msg_item_compressed->uncompressed_data_size = n;
msg_item_compressed->buf_used = compressed_data_count;
- g_free(msg_item);
return msg_item_compressed;
}
/* LZ4 compression failed or did non compress, fallback a non-compressed data is to be sent */
- g_free(msg_item_compressed);
- return NULL;
+ msg_item_compressed.reset();
+ return msg_item_compressed;
}
#endif
-RedPipeItem* RedCharDeviceSpiceVmc::read_one_msg_from_device()
+RedPipeItemPtr
+RedCharDeviceSpiceVmc::read_one_msg_from_device()
{
- RedVmcPipeItem *msg_item;
+ red::shared_ptr<RedVmcPipeItem> msg_item;
int n;
if (!channel->rcc || channel->queued_data >= QUEUED_DATA_LIMIT) {
- return NULL;
+ return RedPipeItemPtr();
}
if (!channel->pipe_item) {
- msg_item = new RedVmcPipeItem();
+ msg_item = red::make_shared<RedVmcPipeItem>();
msg_item->type = SPICE_DATA_COMPRESSION_TYPE_NONE;
} else {
spice_assert(channel->pipe_item->buf_used == 0);
- msg_item = channel->pipe_item;
- channel->pipe_item = NULL;
+ msg_item = std::move(channel->pipe_item);
}
n = read(msg_item->buf, sizeof(msg_item->buf));
if (n > 0) {
spice_debug("read from dev %d", n);
#ifdef USE_LZ4
- RedVmcPipeItem *msg_item_compressed;
+ red::shared_ptr<RedVmcPipeItem> msg_item_compressed;
- msg_item_compressed = try_compress_lz4(channel.get(), n, msg_item);
- if (msg_item_compressed != NULL) {
- spicevmc_red_channel_queue_data(channel.get(), msg_item_compressed);
- return NULL;
+ msg_item_compressed = try_compress_lz4(channel.get(), n, msg_item.get());
+ if (msg_item_compressed) {
+ spicevmc_red_channel_queue_data(channel.get(), std::move(msg_item_compressed));
+ return RedPipeItemPtr();
}
#endif
stat_inc_counter(channel->out_data, n);
msg_item->uncompressed_data_size = n;
msg_item->buf_used = n;
- spicevmc_red_channel_queue_data(channel.get(), msg_item);
- return NULL;
+ spicevmc_red_channel_queue_data(channel.get(), std::move(msg_item));
+ return RedPipeItemPtr();
}
- channel->pipe_item = msg_item;
- return NULL;
+ channel->pipe_item = std::move(msg_item);
+ return RedPipeItemPtr();
}
static void spicevmc_port_send_init(VmcChannelClient *rcc)
{
RedVmcChannel *channel = rcc->get_channel();
SpiceCharDeviceInstance *sin = channel->chardev_sin;
- RedPortInitPipeItem *item = new RedPortInitPipeItem();
+ auto item = red::make_shared<RedPortInitPipeItem>();
item->name.reset(g_strdup(sin->portname));
item->opened = channel->port_opened;
- rcc->pipe_add_push(item);
+ rcc->pipe_add_push(std::move(item));
}
static void spicevmc_port_send_event(RedChannelClient *rcc, uint8_t event)
{
- RedPortEventPipeItem *item = new RedPortEventPipeItem();
+ auto item = red::make_shared<RedPortEventPipeItem>();
item->event = event;
- rcc->pipe_add_push(item);
+ rcc->pipe_add_push(std::move(item));
}
void RedCharDeviceSpiceVmc::remove_client(RedCharDeviceClientOpaque *opaque)
@@ -491,10 +488,10 @@ void VmcChannelClient::release_recv_buf(uint16_t type, uint32_t size, uint8_t *m
}
static void
-spicevmc_red_channel_queue_data(RedVmcChannel *channel, RedVmcPipeItem *item)
+spicevmc_red_channel_queue_data(RedVmcChannel *channel, red::shared_ptr<RedVmcPipeItem>&& item)
{
channel->queued_data += item->buf_used;
- channel->rcc->pipe_add_push(item);
+ channel->rcc->pipe_add_push(std::move(item));
}
static void spicevmc_red_channel_send_data(VmcChannelClient *rcc,
diff --git a/server/stream-channel.cpp b/server/stream-channel.cpp
index e9aac846..08285bf6 100644
--- a/server/stream-channel.cpp
+++ b/server/stream-channel.cpp
@@ -424,7 +424,7 @@ StreamChannel::change_format(const StreamMsgFormat *fmt)
stream_id = (stream_id + 1) % NUM_STREAMS;
// send create stream
- StreamCreateItem *item = new StreamCreateItem();
+ auto item = red::make_shared<StreamCreateItem>();
item->stream_create.id = stream_id;
item->stream_create.flags = SPICE_STREAM_FLAGS_TOP_DOWN;
item->stream_create.codec_type = fmt->codec;
@@ -434,7 +434,7 @@ StreamChannel::change_format(const StreamMsgFormat *fmt)
item->stream_create.src_height = fmt->height;
item->stream_create.dest = (SpiceRect) { 0, 0, fmt->width, fmt->height };
item->stream_create.clip = (SpiceClip) { SPICE_CLIP_TYPE_NONE, NULL };
- pipes_add(item);
+ pipes_add(std::move(item));
// activate stream report if possible
pipes_add_type(RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
@@ -473,7 +473,7 @@ StreamChannel::send_data(const void *data, size_t size, uint32_t mm_time)
update_queue_stat(1, size);
// TODO try to optimize avoiding the copy
memcpy(item->data.data, data, size);
- pipes_add(item);
+ pipes_add(red::shared_ptr<StreamDataItem>(item));
}
void
diff --git a/server/video-stream.cpp b/server/video-stream.cpp
index 48deb7a9..24a2b920 100644
--- a/server/video-stream.cpp
+++ b/server/video-stream.cpp
@@ -70,22 +70,22 @@ StreamCreateDestroyItem::~StreamCreateDestroyItem()
video_stream_agent_unref(display, agent);
}
-static RedPipeItem *video_stream_create_destroy_item_new(VideoStreamAgent *agent,
- int type)
+static RedPipeItemPtr
+video_stream_create_destroy_item_new(VideoStreamAgent *agent, int type)
{
- StreamCreateDestroyItem *item = new StreamCreateDestroyItem(type);
+ auto item = red::make_shared<StreamCreateDestroyItem>(type);
agent->stream->refs++;
item->agent = agent;
return item;
}
-static RedPipeItem *video_stream_create_item_new(VideoStreamAgent *agent)
+static RedPipeItemPtr video_stream_create_item_new(VideoStreamAgent *agent)
{
return video_stream_create_destroy_item_new(agent, RED_PIPE_ITEM_TYPE_STREAM_CREATE);
}
-static RedPipeItem *video_stream_destroy_item_new(VideoStreamAgent *agent)
+static RedPipeItemPtr video_stream_destroy_item_new(VideoStreamAgent *agent)
{
return video_stream_create_destroy_item_new(agent, RED_PIPE_ITEM_TYPE_STREAM_DESTROY);
}
@@ -166,9 +166,9 @@ VideoStreamClipItem::~VideoStreamClipItem()
video_stream_agent_unref(display, stream_agent);
}
-VideoStreamClipItem *video_stream_clip_item_new(VideoStreamAgent *agent)
+red::shared_ptr<VideoStreamClipItem> video_stream_clip_item_new(VideoStreamAgent *agent)
{
- VideoStreamClipItem *item = new VideoStreamClipItem(RED_PIPE_ITEM_TYPE_STREAM_CLIP);
+ auto item = red::make_shared<VideoStreamClipItem>(RED_PIPE_ITEM_TYPE_STREAM_CLIP);
item->stream_agent = agent;
agent->stream->refs++;
@@ -773,8 +773,8 @@ void dcc_create_stream(DisplayChannelClient *dcc, VideoStream *stream)
dcc->pipe_add(video_stream_create_item_new(agent));
if (dcc->test_remote_cap(SPICE_DISPLAY_CAP_STREAM_REPORT)) {
- RedStreamActivateReportItem *report_pipe_item =
- new RedStreamActivateReportItem(RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
+ auto report_pipe_item =
+ red::make_shared<RedStreamActivateReportItem>(RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
agent->report_id = rand();
report_pipe_item->stream_id = stream_id;
@@ -828,7 +828,6 @@ static void dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
if (stream->current &&
region_contains(&stream->current->tree_item.base.rgn, &agent->vis_region)) {
- RedUpgradeItem *upgrade_item;
int n_rects;
/* (1) The caller should detach the drawable from the stream. This will
@@ -841,7 +840,7 @@ static void dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
}
spice_debug("stream %d: upgrade by drawable. box ==>", stream_id);
rect_debug(&stream->current->red_drawable->bbox);
- upgrade_item = new RedUpgradeItem(RED_PIPE_ITEM_TYPE_UPGRADE);
+ auto upgrade_item = red::make_shared<RedUpgradeItem>(RED_PIPE_ITEM_TYPE_UPGRADE);
upgrade_item->drawable = stream->current;
upgrade_item->drawable->refs++;
n_rects = pixman_region32_n_rects(&upgrade_item->drawable->tree_item.base.rgn);
@@ -850,7 +849,7 @@ static void dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
upgrade_item->rects->num_rects = n_rects;
region_ret_rects(&upgrade_item->drawable->tree_item.base.rgn,
upgrade_item->rects->rects, n_rects);
- dcc->pipe_add(upgrade_item);
+ dcc->pipe_add(std::move(upgrade_item));
} else {
SpiceRect upgrade_area;
diff --git a/server/video-stream.h b/server/video-stream.h
index 18ffe67d..3006962e 100644
--- a/server/video-stream.h
+++ b/server/video-stream.h
@@ -104,7 +104,7 @@ struct VideoStreamClipItem: public RedPipeItem {
red::glib_unique_ptr<SpiceClipRects> rects;
};
-VideoStreamClipItem *video_stream_clip_item_new(VideoStreamAgent *agent);
+red::shared_ptr<VideoStreamClipItem> video_stream_clip_item_new(VideoStreamAgent *agent);
struct StreamCreateDestroyItem: public RedPipeItem {
using RedPipeItem::RedPipeItem;