diff options
author | Frediano Ziglio <freddy77@gmail.com> | 2020-06-05 16:59:02 +0100 |
---|---|---|
committer | Frediano Ziglio <freddy77@gmail.com> | 2020-07-13 19:48:08 +0100 |
commit | dd9b78fd7843b31886efb37454d4cdf0c63095e7 (patch) | |
tree | 035625c650cdc9fe3bae2d22bfb41f1e3a9f4674 /server | |
parent | 22fc6a48e65b75fbd1dc90c63bdb0df54c6b72e1 (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.cpp | 2 | ||||
-rw-r--r-- | server/char-device.cpp | 7 | ||||
-rw-r--r-- | server/char-device.h | 3 | ||||
-rw-r--r-- | server/cursor-channel.cpp | 10 | ||||
-rw-r--r-- | server/dcc.cpp | 65 | ||||
-rw-r--r-- | server/dcc.h | 6 | ||||
-rw-r--r-- | server/inputs-channel.cpp | 4 | ||||
-rw-r--r-- | server/main-channel-client.cpp | 92 | ||||
-rw-r--r-- | server/main-channel-client.h | 8 | ||||
-rw-r--r-- | server/red-channel-client.cpp | 58 | ||||
-rw-r--r-- | server/red-channel-client.h | 15 | ||||
-rw-r--r-- | server/red-channel.cpp | 16 | ||||
-rw-r--r-- | server/red-channel.h | 4 | ||||
-rw-r--r-- | server/red-pipe-item.cpp | 2 | ||||
-rw-r--r-- | server/red-stream-device.cpp | 4 | ||||
-rw-r--r-- | server/red-stream-device.h | 2 | ||||
-rw-r--r-- | server/reds.cpp | 63 | ||||
-rw-r--r-- | server/smartcard-channel-client.cpp | 2 | ||||
-rw-r--r-- | server/smartcard.cpp | 37 | ||||
-rw-r--r-- | server/smartcard.h | 2 | ||||
-rw-r--r-- | server/sound.cpp | 6 | ||||
-rw-r--r-- | server/spicevmc.cpp | 69 | ||||
-rw-r--r-- | server/stream-channel.cpp | 6 | ||||
-rw-r--r-- | server/video-stream.cpp | 23 | ||||
-rw-r--r-- | server/video-stream.h | 2 |
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; |