mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-08-10 08:11:50 +00:00
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>
This commit is contained in:
parent
22fc6a48e6
commit
dd9b78fd78
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {};
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user