diff options
author | Frediano Ziglio <freddy77@gmail.com> | 2020-06-04 21:31:05 +0100 |
---|---|---|
committer | Frediano Ziglio <freddy77@gmail.com> | 2020-07-13 19:47:53 +0100 |
commit | a30df693cfa3c7c32339b5db4033831111ff798e (patch) | |
tree | dbebb72c51d5aa1a96c6f41b960f0afc8fa81251 /server | |
parent | 45e964dc5a2e2f86437da0ef3d31ddb650109f40 (diff) |
red-pipe-item: Use inheritance on RedPipeItem
This allows to:
- reuse reference counting;
- avoid having to manually call g_free to release item memory;
- assure item is initialized;
- avoids some manual casts.
It will also allows to use smart pointers.
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 | 4 | ||||
-rw-r--r-- | server/common-graphics-channel.cpp | 5 | ||||
-rw-r--r-- | server/common-graphics-channel.h | 4 | ||||
-rw-r--r-- | server/cursor-channel.cpp | 38 | ||||
-rw-r--r-- | server/dcc-send.cpp | 32 | ||||
-rw-r--r-- | server/dcc.cpp | 132 | ||||
-rw-r--r-- | server/dcc.h | 35 | ||||
-rw-r--r-- | server/display-channel-private.h | 13 | ||||
-rw-r--r-- | server/display-channel.cpp | 4 | ||||
-rw-r--r-- | server/inputs-channel.cpp | 41 | ||||
-rw-r--r-- | server/main-channel-client.cpp | 149 | ||||
-rw-r--r-- | server/red-channel-client.cpp | 33 | ||||
-rw-r--r-- | server/red-channel.cpp | 4 | ||||
-rw-r--r-- | server/red-pipe-item.cpp | 28 | ||||
-rw-r--r-- | server/red-pipe-item.h | 59 | ||||
-rw-r--r-- | server/reds.cpp | 58 | ||||
-rw-r--r-- | server/smartcard-channel-client.cpp | 14 | ||||
-rw-r--r-- | server/smartcard.cpp | 24 | ||||
-rw-r--r-- | server/sound.cpp | 29 | ||||
-rw-r--r-- | server/spicevmc.cpp | 54 | ||||
-rw-r--r-- | server/stream-channel.cpp | 38 | ||||
-rw-r--r-- | server/stream-channel.h | 3 | ||||
-rw-r--r-- | server/video-stream.cpp | 61 | ||||
-rw-r--r-- | server/video-stream.h | 27 |
24 files changed, 405 insertions, 484 deletions
diff --git a/server/cache-item.tmpl.cpp b/server/cache-item.tmpl.cpp index 2b4755f3..3a24ee33 100644 --- a/server/cache-item.tmpl.cpp +++ b/server/cache-item.tmpl.cpp @@ -76,9 +76,9 @@ static void FUNC_NAME(remove)(CHANNELCLIENT *channel_client, RedCacheItem *item) auto id = item->id; RedCachePipeItem *pipe_item = reinterpret_cast<RedCachePipeItem*>(item); - red_pipe_item_init(&pipe_item->base, RED_PIPE_ITEM_TYPE_INVAL_ONE); + new (pipe_item) RedCachePipeItem(); pipe_item->inval_one.id = id; - channel_client->pipe_add_tail(&pipe_item->base); // for now + channel_client->pipe_add_tail(pipe_item); // for now } static int FUNC_NAME(add)(CHANNELCLIENT *channel_client, uint64_t id, size_t size) diff --git a/server/common-graphics-channel.cpp b/server/common-graphics-channel.cpp index c7cac7e9..2a415d65 100644 --- a/server/common-graphics-channel.cpp +++ b/server/common-graphics-channel.cpp @@ -65,3 +65,8 @@ bool CommonGraphicsChannelClient::config_socket() ack_set_client_window(is_low_bandwidth ? WIDE_CLIENT_ACK_WINDOW : NARROW_CLIENT_ACK_WINDOW); return true; } + +RedCachePipeItem::RedCachePipeItem(): + RedPipeItem(RED_PIPE_ITEM_TYPE_INVAL_ONE) +{ +} diff --git a/server/common-graphics-channel.h b/server/common-graphics-channel.h index 455e2d05..4029b59e 100644 --- a/server/common-graphics-channel.h +++ b/server/common-graphics-channel.h @@ -69,8 +69,8 @@ protected: }; /* pipe item used to release a specific cached item on the client */ -struct RedCachePipeItem { - RedPipeItem base; +struct RedCachePipeItem final: public RedPipeItem { + RedCachePipeItem(); SpiceMsgDisplayInvalOne inval_one; }; diff --git a/server/cursor-channel.cpp b/server/cursor-channel.cpp index 835597f4..9fc8f44d 100644 --- a/server/cursor-channel.cpp +++ b/server/cursor-channel.cpp @@ -25,41 +25,35 @@ #include "cursor-channel-client.h" #include "reds.h" -typedef struct RedCursorPipeItem { - RedPipeItem base; +struct RedCursorPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~RedCursorPipeItem(); RedCursorCmd *red_cursor; -} RedCursorPipeItem; - -static void cursor_pipe_item_free(RedPipeItem *pipe_item); +}; static RedCursorPipeItem *cursor_pipe_item_new(RedCursorCmd *cmd) { - RedCursorPipeItem *item = g_new0(RedCursorPipeItem, 1); + RedCursorPipeItem *item = new RedCursorPipeItem(RED_PIPE_ITEM_TYPE_CURSOR); spice_return_val_if_fail(cmd != NULL, NULL); - red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_CURSOR, - cursor_pipe_item_free); item->red_cursor = red_cursor_cmd_ref(cmd); return item; } -static void cursor_pipe_item_free(RedPipeItem *base) +RedCursorPipeItem::~RedCursorPipeItem() { - RedCursorPipeItem *pipe_item = SPICE_UPCAST(RedCursorPipeItem, base); - - red_cursor_cmd_unref(pipe_item->red_cursor); - g_free(pipe_item); + red_cursor_cmd_unref(red_cursor); } static void cursor_channel_set_item(CursorChannel *cursor, RedCursorPipeItem *item) { if (item) { - red_pipe_item_ref(&item->base); + red_pipe_item_ref(item); } if (cursor->item) { - red_pipe_item_unref(&cursor->item->base); + red_pipe_item_unref(cursor->item); } cursor->item = item; } @@ -89,7 +83,7 @@ static void cursor_fill(CursorChannelClient *ccc, RedCursorPipeItem *cursor, if (red_cursor->data_size) { SpiceMarshaller *m2 = spice_marshaller_get_submarshaller(m); - cursor->base.add_to_marshaller(m2, red_cursor->data, red_cursor->data_size); + cursor->add_to_marshaller(m2, red_cursor->data, red_cursor->data_size); } } @@ -178,10 +172,10 @@ void CursorChannelClient::send_item(RedPipeItem *pipe_item) switch (pipe_item->type) { case RED_PIPE_ITEM_TYPE_CURSOR: - red_marshall_cursor(ccc, m, SPICE_UPCAST(RedCursorPipeItem, pipe_item)); + red_marshall_cursor(ccc, m, static_cast<RedCursorPipeItem*>(pipe_item)); break; case RED_PIPE_ITEM_TYPE_INVAL_ONE: - red_marshall_inval(this, m, SPICE_UPCAST(RedCachePipeItem, pipe_item)); + red_marshall_inval(this, m, static_cast<RedCachePipeItem*>(pipe_item)); break; case RED_PIPE_ITEM_TYPE_CURSOR_INIT: reset_cursor_cache(); @@ -235,7 +229,7 @@ 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->base); + red_pipe_item_unref(cursor_pipe_item); return; } @@ -243,9 +237,9 @@ 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->base); + pipes_add(cursor_pipe_item); } else { - red_pipe_item_unref(&cursor_pipe_item->base); + red_pipe_item_unref(cursor_pipe_item); } } @@ -316,7 +310,7 @@ void CursorChannel::on_connect(RedClient *client, RedStream *stream, int migrati CursorChannel::~CursorChannel() { if (item) { - red_pipe_item_unref(&item->base); + red_pipe_item_unref(item); } } diff --git a/server/dcc-send.cpp b/server/dcc-send.cpp index 7c070f3a..641b8c06 100644 --- a/server/dcc-send.cpp +++ b/server/dcc-send.cpp @@ -626,7 +626,7 @@ static bool pipe_rendered_drawables_intersect_with_areas(DisplayChannelClient *d if (pipe_item->type != RED_PIPE_ITEM_TYPE_DRAW) continue; - drawable = SPICE_UPCAST(RedDrawablePipeItem, pipe_item)->drawable; + drawable = static_cast<RedDrawablePipeItem*>(pipe_item)->drawable; if (ring_item_is_linked(&drawable->list_link)) continue; // item hasn't been rendered @@ -719,7 +719,7 @@ static void red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient prev = l->prev; if (pipe_item->type != RED_PIPE_ITEM_TYPE_DRAW) continue; - dpi = SPICE_UPCAST(RedDrawablePipeItem, pipe_item); + dpi = static_cast<RedDrawablePipeItem*>(pipe_item); drawable = dpi->drawable; if (ring_item_is_linked(&drawable->list_link)) continue; // item hasn't been rendered @@ -1969,8 +1969,8 @@ static void red_marshall_image(DisplayChannelClient *dcc, spice_marshall_Image(src_bitmap_out, &red_image, &bitmap_palette_out, &lzplt_palette_out); - item->base.add_to_marshaller(src_bitmap_out, item->data, - bitmap.y * bitmap.stride); + item->add_to_marshaller(src_bitmap_out, item->data, + bitmap.y * bitmap.stride); region_remove(surface_lossy_region, ©.base.box); } spice_chunks_destroy(chunks); @@ -2286,7 +2286,7 @@ static void marshall_gl_draw(RedChannelClient *rcc, SpiceMarshaller *m, RedPipeItem *item) { - RedGlDrawItem *p = SPICE_UPCAST(RedGlDrawItem, item); + RedGlDrawItem *p = static_cast<RedGlDrawItem*>(item); rcc->init_send_data(SPICE_MSG_DISPLAY_GL_DRAW); spice_marshall_msg_display_gl_draw(m, &p->draw); @@ -2335,34 +2335,34 @@ void DisplayChannelClient::send_item(RedPipeItem *pipe_item) ::reset_send_data(dcc); switch (pipe_item->type) { case RED_PIPE_ITEM_TYPE_DRAW: { - RedDrawablePipeItem *dpi = SPICE_UPCAST(RedDrawablePipeItem, pipe_item); + RedDrawablePipeItem *dpi = static_cast<RedDrawablePipeItem*>(pipe_item); marshall_qxl_drawable(this, m, dpi); break; } case RED_PIPE_ITEM_TYPE_INVAL_ONE: - marshall_inval_palette(this, m, SPICE_UPCAST(RedCachePipeItem, pipe_item)); + marshall_inval_palette(this, m, static_cast<RedCachePipeItem*>(pipe_item)); break; case RED_PIPE_ITEM_TYPE_STREAM_CREATE: { - StreamCreateDestroyItem *item = SPICE_UPCAST(StreamCreateDestroyItem, pipe_item); + StreamCreateDestroyItem *item = static_cast<StreamCreateDestroyItem*>(pipe_item); marshall_stream_start(this, m, item->agent); break; } case RED_PIPE_ITEM_TYPE_STREAM_CLIP: - marshall_stream_clip(this, m, SPICE_UPCAST(VideoStreamClipItem, pipe_item)); + marshall_stream_clip(this, m, static_cast<VideoStreamClipItem*>(pipe_item)); break; case RED_PIPE_ITEM_TYPE_STREAM_DESTROY: { - StreamCreateDestroyItem *item = SPICE_UPCAST(StreamCreateDestroyItem, pipe_item); + StreamCreateDestroyItem *item = static_cast<StreamCreateDestroyItem*>(pipe_item); marshall_stream_end(this, m, item->agent); break; } case RED_PIPE_ITEM_TYPE_UPGRADE: - marshall_upgrade(this, m, SPICE_UPCAST(RedUpgradeItem, pipe_item)); + marshall_upgrade(this, m, static_cast<RedUpgradeItem*>(pipe_item)); break; case RED_PIPE_ITEM_TYPE_MIGRATE_DATA: display_channel_marshall_migrate_data(this, m); break; case RED_PIPE_ITEM_TYPE_IMAGE: - red_marshall_image(this, m, SPICE_UPCAST(RedImageItem, pipe_item)); + red_marshall_image(this, m, static_cast<RedImageItem*>(pipe_item)); break; case RED_PIPE_ITEM_TYPE_PIXMAP_SYNC: display_channel_marshall_pixmap_sync(this, m); @@ -2375,23 +2375,23 @@ void DisplayChannelClient::send_item(RedPipeItem *pipe_item) init_send_data(SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES); break; case RED_PIPE_ITEM_TYPE_CREATE_SURFACE: { - RedSurfaceCreateItem *surface_create = SPICE_UPCAST(RedSurfaceCreateItem, pipe_item); + RedSurfaceCreateItem *surface_create = static_cast<RedSurfaceCreateItem*>(pipe_item); marshall_surface_create(this, m, &surface_create->surface_create); break; } case RED_PIPE_ITEM_TYPE_DESTROY_SURFACE: { - RedSurfaceDestroyItem *surface_destroy = SPICE_UPCAST(RedSurfaceDestroyItem, pipe_item); + RedSurfaceDestroyItem *surface_destroy = static_cast<RedSurfaceDestroyItem*>(pipe_item); marshall_surface_destroy(this, m, surface_destroy->surface_destroy.surface_id); break; } case RED_PIPE_ITEM_TYPE_MONITORS_CONFIG: { - RedMonitorsConfigItem *monconf_item = SPICE_UPCAST(RedMonitorsConfigItem, pipe_item); + RedMonitorsConfigItem *monconf_item = static_cast<RedMonitorsConfigItem*>(pipe_item); marshall_monitors_config(this, m, monconf_item->monitors_config); break; } case RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT: { RedStreamActivateReportItem *report_item = - SPICE_UPCAST(RedStreamActivateReportItem, pipe_item); + static_cast<RedStreamActivateReportItem*>(pipe_item); marshall_stream_activate_report(this, m, report_item); break; } diff --git a/server/dcc.cpp b/server/dcc.cpp index 3fd58535..16539726 100644 --- a/server/dcc.cpp +++ b/server/dcc.cpp @@ -70,25 +70,18 @@ DisplayChannelClient::~DisplayChannelClient() g_clear_pointer(&priv->client_preferred_video_codecs, g_array_unref); } -static RedSurfaceCreateItem *red_surface_create_item_new(RedChannel* channel, - uint32_t surface_id, - uint32_t width, - uint32_t height, - uint32_t format, - uint32_t flags) +RedSurfaceCreateItem::RedSurfaceCreateItem(uint32_t surface_id, + uint32_t width, + uint32_t height, + uint32_t format, + uint32_t flags): + RedPipeItem(RED_PIPE_ITEM_TYPE_CREATE_SURFACE) { - RedSurfaceCreateItem *create; - - create = g_new(RedSurfaceCreateItem, 1); - - create->surface_create.surface_id = surface_id; - create->surface_create.width = width; - create->surface_create.height = height; - create->surface_create.flags = flags; - create->surface_create.format = format; - - red_pipe_item_init(&create->base, RED_PIPE_ITEM_TYPE_CREATE_SURFACE); - return create; + surface_create.surface_id = surface_id; + surface_create.width = width; + surface_create.height = height; + surface_create.flags = flags; + surface_create.format = format; } bool dcc_drawable_is_in_pipe(DisplayChannelClient *dcc, Drawable *drawable) @@ -129,10 +122,10 @@ bool dcc_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surfac l = l->next; if (item->type == RED_PIPE_ITEM_TYPE_DRAW) { - dpi = SPICE_UPCAST(RedDrawablePipeItem, item); + dpi = static_cast<RedDrawablePipeItem*>(item); drawable = dpi->drawable; } else if (item->type == RED_PIPE_ITEM_TYPE_UPGRADE) { - drawable = SPICE_UPCAST(RedUpgradeItem, item)->drawable; + drawable = static_cast<RedUpgradeItem*>(item)->drawable; } else { continue; } @@ -189,12 +182,16 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id) return; } surface = &display->priv->surfaces[surface_id]; - create = red_surface_create_item_new(display, - surface_id, surface->context.width, - surface->context.height, - surface->context.format, flags); + create = new 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->base); + dcc->pipe_add(create); +} + +RedImageItem::RedImageItem(): + RedPipeItem(RED_PIPE_ITEM_TYPE_IMAGE) +{ } // adding the pipe item after pos. If pos == NULL, adding to head. @@ -219,9 +216,7 @@ dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id, bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8; stride = width * bpp; - item = (RedImageItem *)g_malloc(height * stride + sizeof(RedImageItem)); - - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_IMAGE); + item = new (height * stride) RedImageItem(); item->surface_id = surface_id; item->image_format = @@ -250,9 +245,9 @@ dcc_add_surface_area_image(DisplayChannelClient *dcc, int surface_id, } if (pipe_item_pos) { - dcc->pipe_add_after_pos(&item->base, pipe_item_pos); + dcc->pipe_add_after_pos(item, pipe_item_pos); } else { - dcc->pipe_add(&item->base); + dcc->pipe_add(item); } } @@ -308,14 +303,15 @@ static void add_drawable_surface_images(DisplayChannelClient *dcc, Drawable *dra dcc_push_surface_image(dcc, drawable->surface_id); } -static void red_drawable_pipe_item_free(RedPipeItem *item) +RedDrawablePipeItem::RedDrawablePipeItem(): + RedPipeItem(RED_PIPE_ITEM_TYPE_DRAW) { - RedDrawablePipeItem *dpi = SPICE_UPCAST(RedDrawablePipeItem, item); - spice_assert(item->refcount == 0); +} - dpi->drawable->pipes = g_list_remove(dpi->drawable->pipes, dpi); - drawable_unref(dpi->drawable); - g_free(dpi); +RedDrawablePipeItem::~RedDrawablePipeItem() +{ + drawable->pipes = g_list_remove(drawable->pipes, this); + drawable_unref(drawable); } static RedDrawablePipeItem *red_drawable_pipe_item_new(DisplayChannelClient *dcc, @@ -323,12 +319,10 @@ static RedDrawablePipeItem *red_drawable_pipe_item_new(DisplayChannelClient *dcc { RedDrawablePipeItem *dpi; - dpi = g_new0(RedDrawablePipeItem, 1); + dpi = new RedDrawablePipeItem; dpi->drawable = drawable; dpi->dcc = dcc; drawable->pipes = g_list_prepend(drawable->pipes, dpi); - red_pipe_item_init_full(&dpi->base, RED_PIPE_ITEM_TYPE_DRAW, - red_drawable_pipe_item_free); drawable->refs++; return dpi; } @@ -338,7 +332,7 @@ void dcc_prepend_drawable(DisplayChannelClient *dcc, Drawable *drawable) RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable); add_drawable_surface_images(dcc, drawable); - dcc->pipe_add(&dpi->base); + dcc->pipe_add(dpi); } void dcc_append_drawable(DisplayChannelClient *dcc, Drawable *drawable) @@ -346,7 +340,7 @@ void dcc_append_drawable(DisplayChannelClient *dcc, Drawable *drawable) RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable); add_drawable_surface_images(dcc, drawable); - dcc->pipe_add_tail(&dpi->base); + dcc->pipe_add_tail(dpi); } void dcc_add_drawable_after(DisplayChannelClient *dcc, Drawable *drawable, RedPipeItem *pos) @@ -354,7 +348,7 @@ void dcc_add_drawable_after(DisplayChannelClient *dcc, Drawable *drawable, RedPi RedDrawablePipeItem *dpi = red_drawable_pipe_item_new(dcc, drawable); add_drawable_surface_images(dcc, drawable); - dcc->pipe_add_after(&dpi->base, pos); + dcc->pipe_add_after(dpi, pos); } static void dcc_init_stream_agents(DisplayChannelClient *dcc) @@ -498,28 +492,18 @@ void dcc_video_stream_agent_clip(DisplayChannelClient* dcc, VideoStreamAgent *ag { VideoStreamClipItem *item = video_stream_clip_item_new(agent); - dcc->pipe_add(&item->base); + dcc->pipe_add(item); } -static void red_monitors_config_item_free(RedPipeItem *pipe_item) +RedMonitorsConfigItem::~RedMonitorsConfigItem() { - RedMonitorsConfigItem *item = SPICE_UPCAST(RedMonitorsConfigItem, pipe_item); - - monitors_config_unref(item->monitors_config); - g_free(item); + monitors_config_unref(monitors_config); } -static RedMonitorsConfigItem *red_monitors_config_item_new(RedChannel* channel, - MonitorsConfig *monitors_config) +RedMonitorsConfigItem::RedMonitorsConfigItem(MonitorsConfig *init_monitors_config): + RedPipeItem(RED_PIPE_ITEM_TYPE_MONITORS_CONFIG) { - RedMonitorsConfigItem *mci; - - mci = g_new(RedMonitorsConfigItem, 1); - mci->monitors_config = monitors_config_ref(monitors_config); - - red_pipe_item_init_full(&mci->base, RED_PIPE_ITEM_TYPE_MONITORS_CONFIG, - red_monitors_config_item_free); - return mci; + monitors_config = monitors_config_ref(init_monitors_config); } void dcc_push_monitors_config(DisplayChannelClient *dcc) @@ -537,26 +521,18 @@ void dcc_push_monitors_config(DisplayChannelClient *dcc) return; } - mci = red_monitors_config_item_new(dcc->get_channel(), - monitors_config); - dcc->pipe_add(&mci->base); + mci = new RedMonitorsConfigItem(monitors_config); + dcc->pipe_add(mci); } -static RedSurfaceDestroyItem *red_surface_destroy_item_new(uint32_t surface_id) +RedSurfaceDestroyItem::RedSurfaceDestroyItem(uint32_t surface_id): + RedPipeItem(RED_PIPE_ITEM_TYPE_DESTROY_SURFACE) { - RedSurfaceDestroyItem *destroy; - - destroy = g_new(RedSurfaceDestroyItem, 1); - destroy->surface_destroy.surface_id = surface_id; - red_pipe_item_init(&destroy->base, RED_PIPE_ITEM_TYPE_DESTROY_SURFACE); - - return destroy; + surface_destroy.surface_id = surface_id; } RedPipeItem *dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num) { - RedGlScanoutUnixItem *item; - /* FIXME: on !unix peer, start streaming with a video codec */ if (!red_stream_is_plain_unix(rcc->get_stream()) || !rcc->test_remote_cap(SPICE_DISPLAY_CAP_GL_SCANOUT)) { @@ -566,10 +542,7 @@ RedPipeItem *dcc_gl_scanout_item_new(RedChannelClient *rcc, void *data, int num) return NULL; } - item = g_new(RedGlScanoutUnixItem, 1); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_GL_SCANOUT); - - return &item->base; + return new RedGlScanoutUnixItem(RED_PIPE_ITEM_TYPE_GL_SCANOUT); } XXX_CAST(RedChannelClient, DisplayChannelClient, DISPLAY_CHANNEL_CLIENT); @@ -589,11 +562,10 @@ RedPipeItem *dcc_gl_draw_item_new(RedChannelClient *rcc, void *data, int num) } dcc->priv->gl_draw_ongoing = TRUE; - item = g_new(RedGlDrawItem, 1); + item = new RedGlDrawItem(RED_PIPE_ITEM_TYPE_GL_DRAW); item->draw = *draw; - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_GL_DRAW); - return &item->base; + return item; } void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id) @@ -613,8 +585,8 @@ void dcc_destroy_surface(DisplayChannelClient *dcc, uint32_t surface_id) } dcc->priv->surface_client_created[surface_id] = FALSE; - destroy = red_surface_destroy_item_new(surface_id); - dcc->pipe_add(&destroy->base); + destroy = new RedSurfaceDestroyItem(surface_id); + dcc->pipe_add(destroy); } #define MIN_DIMENSION_TO_QUIC 3 diff --git a/server/dcc.h b/server/dcc.h index 3172ba1b..3931686d 100644 --- a/server/dcc.h +++ b/server/dcc.h @@ -96,22 +96,26 @@ typedef struct FreeList { #define DCC_TO_DC(dcc) ((DisplayChannel*) dcc->get_channel()) -typedef struct RedSurfaceCreateItem { - RedPipeItem base; +struct RedSurfaceCreateItem: public RedPipeItem { + RedSurfaceCreateItem(uint32_t surface_id, + uint32_t width, + uint32_t height, + uint32_t format, + uint32_t flags); SpiceMsgSurfaceCreate surface_create; -} RedSurfaceCreateItem; +}; -typedef struct RedGlScanoutUnixItem { - RedPipeItem base; -} RedGlScanoutUnixItem; +struct RedGlScanoutUnixItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; +}; -typedef struct RedGlDrawItem { - RedPipeItem base; +struct RedGlDrawItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; SpiceMsgDisplayGlDraw draw; -} RedGlDrawItem; +}; -typedef struct RedImageItem { - RedPipeItem base; +struct RedImageItem final: public RedPipeItem { + RedImageItem(); SpicePoint pos; int width; int height; @@ -122,13 +126,14 @@ typedef struct RedImageItem { uint32_t image_flags; int can_lossy; uint8_t data[0]; -} RedImageItem; +}; -typedef struct RedDrawablePipeItem { - RedPipeItem base; +struct RedDrawablePipeItem: public RedPipeItem { + RedDrawablePipeItem(); + ~RedDrawablePipeItem(); Drawable *drawable; DisplayChannelClient *dcc; -} RedDrawablePipeItem; +}; DisplayChannelClient* dcc_new (DisplayChannel *display, RedClient *client, diff --git a/server/display-channel-private.h b/server/display-channel-private.h index 8e8ee683..04552776 100644 --- a/server/display-channel-private.h +++ b/server/display-channel-private.h @@ -139,10 +139,11 @@ struct DisplayChannelPrivate GLIST_FOREACH((_channel ? _channel->get_clients() : NULL), \ DisplayChannelClient, _data) -typedef struct RedMonitorsConfigItem { - RedPipeItem base; +struct RedMonitorsConfigItem: public RedPipeItem { + RedMonitorsConfigItem(MonitorsConfig *monitors_config); + ~RedMonitorsConfigItem(); MonitorsConfig *monitors_config; -} RedMonitorsConfigItem; +}; enum { RED_PIPE_ITEM_TYPE_DRAW = RED_PIPE_ITEM_TYPE_COMMON_LAST, @@ -181,10 +182,10 @@ uint32_t display_channel_generate_uid(DisplayChannel *display); int display_channel_get_video_stream_id(DisplayChannel *display, VideoStream *stream); VideoStream *display_channel_get_nth_video_stream(DisplayChannel *display, gint i); -typedef struct RedSurfaceDestroyItem { - RedPipeItem base; +struct RedSurfaceDestroyItem: public RedPipeItem { + RedSurfaceDestroyItem(uint32_t surface_id); SpiceMsgSurfaceDestroy surface_destroy; -} RedSurfaceDestroyItem; +}; static inline int is_equal_path(SpicePath *path1, SpicePath *path2) { diff --git a/server/display-channel.cpp b/server/display-channel.cpp index 5261b348..79679c4d 100644 --- a/server/display-channel.cpp +++ b/server/display-channel.cpp @@ -327,7 +327,7 @@ static void pipes_add_drawable_after(DisplayChannel *display, dpi_pos_after = (RedDrawablePipeItem*) l->data; num_other_linked++; - dcc_add_drawable_after(dpi_pos_after->dcc, drawable, &dpi_pos_after->base); + dcc_add_drawable_after(dpi_pos_after->dcc, drawable, dpi_pos_after); } if (num_other_linked == 0) { @@ -387,7 +387,7 @@ static void drawable_remove_from_pipes(Drawable *drawable) RedChannelClient *rcc; rcc = dpi->dcc; - rcc->pipe_remove_and_release(&dpi->base); + rcc->pipe_remove_and_release(dpi); } } diff --git a/server/inputs-channel.cpp b/server/inputs-channel.cpp index d712220f..aede5c2a 100644 --- a/server/inputs-channel.cpp +++ b/server/inputs-channel.cpp @@ -86,15 +86,15 @@ RedsState* spice_tablet_state_get_server(SpiceTabletState *st) return st->reds; } -typedef struct RedKeyModifiersPipeItem { - RedPipeItem base; +struct RedKeyModifiersPipeItem: public RedPipeItem { + RedKeyModifiersPipeItem(uint8_t modifiers); uint8_t modifiers; -} RedKeyModifiersPipeItem; +}; -typedef struct RedInputsInitPipeItem { - RedPipeItem base; +struct RedInputsInitPipeItem: public RedPipeItem { + RedInputsInitPipeItem(uint8_t modifiers); uint8_t modifiers; -} RedInputsInitPipeItem; +}; #define KEY_MODIFIERS_TTL (MSEC_PER_SEC * 2) @@ -194,13 +194,10 @@ static uint8_t kbd_get_leds(SpiceKbdInstance *sin) return sif->get_leds(sin); } -static RedPipeItem *red_inputs_key_modifiers_item_new(uint8_t modifiers) +RedKeyModifiersPipeItem::RedKeyModifiersPipeItem(uint8_t init_modifiers): + RedPipeItem(RED_PIPE_ITEM_KEY_MODIFIERS), + modifiers(init_modifiers) { - RedKeyModifiersPipeItem *item = g_new(RedKeyModifiersPipeItem, 1); - - red_pipe_item_init(&item->base, RED_PIPE_ITEM_KEY_MODIFIERS); - item->modifiers = modifiers; - return &item->base; } void InputsChannelClient::send_item(RedPipeItem *base) @@ -214,7 +211,7 @@ void InputsChannelClient::send_item(RedPipeItem *base) init_send_data(SPICE_MSG_INPUTS_KEY_MODIFIERS); key_modifiers.modifiers = - SPICE_UPCAST(RedKeyModifiersPipeItem, base)->modifiers; + static_cast<RedKeyModifiersPipeItem*>(base)->modifiers; spice_marshall_msg_inputs_key_modifiers(m, &key_modifiers); break; } @@ -224,7 +221,7 @@ void InputsChannelClient::send_item(RedPipeItem *base) init_send_data(SPICE_MSG_INPUTS_INIT); inputs_init.keyboard_modifiers = - SPICE_UPCAST(RedInputsInitPipeItem, base)->modifiers; + static_cast<RedInputsInitPipeItem*>(base)->modifiers; spice_marshall_msg_inputs_init(m, &inputs_init); break; } @@ -432,14 +429,16 @@ void InputsChannel::release_keys() } } -void InputsChannelClient::pipe_add_init() +RedInputsInitPipeItem::RedInputsInitPipeItem(uint8_t init_modifiers): + RedPipeItem(RED_PIPE_ITEM_INPUTS_INIT), + modifiers(init_modifiers) { - RedInputsInitPipeItem *item = g_new(RedInputsInitPipeItem, 1); - InputsChannel *inputs = get_channel(); +} - red_pipe_item_init(&item->base, RED_PIPE_ITEM_INPUTS_INIT); - item->modifiers = kbd_get_leds(inputs->keyboard); - pipe_add_push(&item->base); +void InputsChannelClient::pipe_add_init() +{ + auto modifiers = kbd_get_leds(get_channel()->keyboard); + pipe_add_push(new RedInputsInitPipeItem(modifiers)); } void InputsChannel::on_connect(RedClient *client, RedStream *stream, int migration, @@ -464,7 +463,7 @@ void InputsChannel::push_keyboard_modifiers() if (!is_connected() || src_during_migrate) { return; } - pipes_add(red_inputs_key_modifiers_item_new(modifiers)); + pipes_add(new 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 90df5704..139d2a34 100644 --- a/server/main-channel-client.cpp +++ b/server/main-channel-client.cpp @@ -61,65 +61,67 @@ struct MainChannelClientPrivate { uint8_t recv_buf[MAIN_CHANNEL_RECEIVE_BUF_SIZE]; }; -typedef struct RedPingPipeItem { - RedPipeItem base; +struct RedPingPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; int size; -} RedPingPipeItem; +}; -typedef struct RedTokensPipeItem { - RedPipeItem base; +struct RedTokensPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; int tokens; -} RedTokensPipeItem; +}; -typedef struct RedAgentDataPipeItem { - RedPipeItem base; +struct RedAgentDataPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~RedAgentDataPipeItem(); uint8_t* data; size_t len; spice_marshaller_item_free_func free_data; void *opaque; -} RedAgentDataPipeItem; +}; -typedef struct RedInitPipeItem { - RedPipeItem base; +struct RedInitPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; int connection_id; int display_channels_hint; int current_mouse_mode; int is_client_mouse_allowed; int multi_media_time; int ram_hint; -} RedInitPipeItem; +}; -typedef struct RedNamePipeItem { - RedPipeItem base; +struct RedNamePipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; SpiceMsgMainName msg; -} RedNamePipeItem; +}; -typedef struct RedUuidPipeItem { - RedPipeItem base; +struct RedUuidPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; SpiceMsgMainUuid msg; -} RedUuidPipeItem; +}; -typedef struct RedNotifyPipeItem { - RedPipeItem base; +struct RedNotifyPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~RedNotifyPipeItem(); char *msg; -} RedNotifyPipeItem; +}; -typedef struct RedMouseModePipeItem { - RedPipeItem base; +struct RedMouseModePipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; SpiceMouseMode current_mode; int is_client_mouse_allowed; -} RedMouseModePipeItem; +}; -typedef struct RedMultiMediaTimePipeItem { - RedPipeItem base; +struct RedMultiMediaTimePipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; uint32_t time; -} RedMultiMediaTimePipeItem; +}; -typedef struct RedRegisteredChannelPipeItem { - RedPipeItem base; +struct RedRegisteredChannelPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; uint32_t channel_type; uint32_t channel_id; -} RedRegisteredChannelPipeItem; +}; #define ZERO_BUF_SIZE 4096 @@ -157,21 +159,17 @@ void MainChannelClient::on_disconnect() static void main_channel_client_push_ping(MainChannelClient *mcc, int size); -static void main_notify_item_free(RedPipeItem *base) +RedNotifyPipeItem::~RedNotifyPipeItem() { - RedNotifyPipeItem *data = SPICE_UPCAST(RedNotifyPipeItem, base); - g_free(data->msg); - g_free(data); + g_free(msg); } static RedPipeItem *main_notify_item_new(const char *msg, int num) { - RedNotifyPipeItem *item = g_new(RedNotifyPipeItem, 1); + RedNotifyPipeItem *item = new RedNotifyPipeItem(RED_PIPE_ITEM_TYPE_MAIN_NOTIFY); - red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_MAIN_NOTIFY, - main_notify_item_free); item->msg = g_strdup(msg); - return &item->base; + return item; } void MainChannelClient::start_net_test(int test_rate) @@ -195,11 +193,10 @@ void MainChannelClient::start_net_test(int test_rate) static RedPipeItem *red_ping_item_new(int size) { - RedPingPipeItem *item = g_new(RedPingPipeItem, 1); + RedPingPipeItem *item = new RedPingPipeItem(RED_PIPE_ITEM_TYPE_MAIN_PING); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_PING); item->size = size; - return &item->base; + return item; } static void main_channel_client_push_ping(MainChannelClient *mcc, int size) @@ -210,11 +207,10 @@ static void main_channel_client_push_ping(MainChannelClient *mcc, int size) static RedPipeItem *main_agent_tokens_item_new(uint32_t num_tokens) { - RedTokensPipeItem *item = g_new(RedTokensPipeItem, 1); + RedTokensPipeItem *item = new RedTokensPipeItem(RED_PIPE_ITEM_TYPE_MAIN_AGENT_TOKEN); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_AGENT_TOKEN); item->tokens = num_tokens; - return &item->base; + return item; } @@ -225,26 +221,22 @@ void MainChannelClient::push_agent_tokens(uint32_t num_tokens) pipe_add_push(item); } -static void main_agent_data_item_free(RedPipeItem *base) +RedAgentDataPipeItem::~RedAgentDataPipeItem() { - RedAgentDataPipeItem *item = SPICE_UPCAST(RedAgentDataPipeItem, base); - item->free_data(item->data, item->opaque); - g_free(item); + free_data(data, opaque); } static RedPipeItem *main_agent_data_item_new(uint8_t* data, size_t len, spice_marshaller_item_free_func free_data, void *opaque) { - RedAgentDataPipeItem *item = g_new(RedAgentDataPipeItem, 1); + RedAgentDataPipeItem *item = new RedAgentDataPipeItem(RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA); - red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA, - main_agent_data_item_free); item->data = data; item->len = len; item->free_data = free_data; item->opaque = opaque; - return &item->base; + return item; } void MainChannelClient::push_agent_data(uint8_t *data, size_t len, @@ -264,16 +256,15 @@ static RedPipeItem *main_init_item_new(int connection_id, int multi_media_time, int ram_hint) { - RedInitPipeItem *item = g_new(RedInitPipeItem, 1); + RedInitPipeItem *item = new RedInitPipeItem(RED_PIPE_ITEM_TYPE_MAIN_INIT); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_INIT); item->connection_id = connection_id; item->display_channels_hint = display_channels_hint; item->current_mouse_mode = current_mouse_mode; item->is_client_mouse_allowed = is_client_mouse_allowed; item->multi_media_time = multi_media_time; item->ram_hint = ram_hint; - return &item->base; + return item; } void MainChannelClient::push_init(int display_channels_hint, @@ -291,13 +282,11 @@ void MainChannelClient::push_init(int display_channels_hint, static RedPipeItem *main_name_item_new(const char *name) { - RedNamePipeItem *item = (RedNamePipeItem*) g_malloc(sizeof(RedNamePipeItem) + strlen(name) + 1); - - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_NAME); + RedNamePipeItem *item = new (strlen(name) + 1) RedNamePipeItem(RED_PIPE_ITEM_TYPE_MAIN_NAME); item->msg.name_len = strlen(name) + 1; memcpy(&item->msg.name, name, item->msg.name_len); - return &item->base; + return item; } void MainChannelClient::push_name(const char *name) @@ -313,12 +302,11 @@ void MainChannelClient::push_name(const char *name) static RedPipeItem *main_uuid_item_new(const uint8_t uuid[16]) { - RedUuidPipeItem *item = g_new(RedUuidPipeItem, 1); + RedUuidPipeItem *item = new RedUuidPipeItem(RED_PIPE_ITEM_TYPE_MAIN_UUID); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_UUID); memcpy(item->msg.uuid, uuid, sizeof(item->msg.uuid)); - return &item->base; + return item; } void MainChannelClient::push_uuid(const uint8_t uuid[16]) @@ -340,34 +328,31 @@ void MainChannelClient::push_notify(const char *msg) RedPipeItem *main_mouse_mode_item_new(SpiceMouseMode current_mode, int is_client_mouse_allowed) { - RedMouseModePipeItem *item = g_new(RedMouseModePipeItem, 1); + RedMouseModePipeItem *item = new RedMouseModePipeItem(RED_PIPE_ITEM_TYPE_MAIN_MOUSE_MODE); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_MOUSE_MODE); item->current_mode = current_mode; item->is_client_mouse_allowed = is_client_mouse_allowed; - return &item->base; + return item; } RedPipeItem *main_multi_media_time_item_new(uint32_t mm_time) { RedMultiMediaTimePipeItem *item; - item = g_new(RedMultiMediaTimePipeItem, 1); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_MULTI_MEDIA_TIME); + item = new RedMultiMediaTimePipeItem(RED_PIPE_ITEM_TYPE_MAIN_MULTI_MEDIA_TIME); item->time = mm_time; - return &item->base; + return item; } RedPipeItem *registered_channel_item_new(RedChannel *channel) { RedRegisteredChannelPipeItem *item; - item = g_new0(RedRegisteredChannelPipeItem, 1); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_MAIN_REGISTERED_CHANNEL); + item = new RedRegisteredChannelPipeItem(RED_PIPE_ITEM_TYPE_MAIN_REGISTERED_CHANNEL); item->channel_type = channel->type(); item->channel_id = channel->id(); - return &item->base; + return item; } void MainChannelClient::handle_migrate_connected(int success, int seamless) @@ -684,7 +669,7 @@ static void main_channel_marshall_agent_data(RedChannelClient *rcc, { rcc->init_send_data(SPICE_MSG_MAIN_AGENT_DATA); /* since pipe item owns the data, keep it alive until it's sent */ - item->base.add_to_marshaller(m, item->data, item->len); + item->add_to_marshaller(m, item->data, item->len); } static void main_channel_marshall_migrate_data_item(RedChannelClient *rcc, @@ -863,22 +848,22 @@ void MainChannelClient::send_item(RedPipeItem *base) break; case RED_PIPE_ITEM_TYPE_MAIN_PING: main_channel_marshall_ping(this, m, - SPICE_UPCAST(RedPingPipeItem, base)); + static_cast<RedPingPipeItem*>(base)); break; case RED_PIPE_ITEM_TYPE_MAIN_MOUSE_MODE: main_channel_marshall_mouse_mode(this, m, - SPICE_UPCAST(RedMouseModePipeItem, base)); + static_cast<RedMouseModePipeItem*>(base)); break; case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DISCONNECTED: main_channel_marshall_agent_disconnected(this, m, base); break; case RED_PIPE_ITEM_TYPE_MAIN_AGENT_TOKEN: main_channel_marshall_tokens(this, m, - SPICE_UPCAST(RedTokensPipeItem, base)); + static_cast<RedTokensPipeItem*>(base)); break; case RED_PIPE_ITEM_TYPE_MAIN_AGENT_DATA: main_channel_marshall_agent_data(this, m, - SPICE_UPCAST(RedAgentDataPipeItem, base)); + static_cast<RedAgentDataPipeItem*>(base)); break; case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_DATA: main_channel_marshall_migrate_data_item(this, m, base); @@ -886,11 +871,11 @@ void MainChannelClient::send_item(RedPipeItem *base) case RED_PIPE_ITEM_TYPE_MAIN_INIT: priv->init_sent = TRUE; main_channel_marshall_init(this, m, - SPICE_UPCAST(RedInitPipeItem, base)); + static_cast<RedInitPipeItem*>(base)); break; case RED_PIPE_ITEM_TYPE_MAIN_NOTIFY: main_channel_marshall_notify(this, m, - SPICE_UPCAST(RedNotifyPipeItem, base)); + static_cast<RedNotifyPipeItem*>(base)); break; case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_BEGIN: main_channel_marshall_migrate_begin(m, this, base); @@ -900,18 +885,18 @@ void MainChannelClient::send_item(RedPipeItem *base) break; case RED_PIPE_ITEM_TYPE_MAIN_MULTI_MEDIA_TIME: main_channel_marshall_multi_media_time(this, m, - SPICE_UPCAST(RedMultiMediaTimePipeItem, base)); + static_cast<RedMultiMediaTimePipeItem*>(base)); break; case RED_PIPE_ITEM_TYPE_MAIN_MIGRATE_SWITCH_HOST: main_channel_marshall_migrate_switch(m, this, base); break; case RED_PIPE_ITEM_TYPE_MAIN_NAME: init_send_data(SPICE_MSG_MAIN_NAME); - spice_marshall_msg_main_name(m, &SPICE_UPCAST(RedNamePipeItem, base)->msg); + spice_marshall_msg_main_name(m, &static_cast<RedNamePipeItem*>(base)->msg); break; case RED_PIPE_ITEM_TYPE_MAIN_UUID: init_send_data(SPICE_MSG_MAIN_UUID); - spice_marshall_msg_main_uuid(m, &SPICE_UPCAST(RedUuidPipeItem, base)->msg); + spice_marshall_msg_main_uuid(m, &static_cast<RedUuidPipeItem*>(base)->msg); break; case RED_PIPE_ITEM_TYPE_MAIN_AGENT_CONNECTED_TOKENS: main_channel_marshall_agent_connected(m, this, base); @@ -925,7 +910,7 @@ void MainChannelClient::send_item(RedPipeItem *base) return; } main_channel_marshall_registered_channel(this, m, - SPICE_UPCAST(RedRegisteredChannelPipeItem, base)); + static_cast<RedRegisteredChannelPipeItem*>(base)); break; default: break; diff --git a/server/red-channel-client.cpp b/server/red-channel-client.cpp index 38934db5..eed6a53a 100644 --- a/server/red-channel-client.cpp +++ b/server/red-channel-client.cpp @@ -239,15 +239,15 @@ static const SpiceDataHeaderOpaque mini_header_wrapper = {NULL, sizeof(SpiceMini #define PING_TEST_LONG_TIMEOUT_MS (MSEC_PER_SEC * 60 * 5) #define PING_TEST_IDLE_NET_TIMEOUT_MS (MSEC_PER_SEC / 10) -typedef struct RedEmptyMsgPipeItem { - RedPipeItem base; +struct RedEmptyMsgPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; int msg; -} RedEmptyMsgPipeItem; +}; -typedef struct MarkerPipeItem { - RedPipeItem base; +struct MarkerPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; bool item_sent; -} MarkerPipeItem; +}; void RedChannelClientPrivate::start_ping_timer(uint32_t timeout) { @@ -488,7 +488,7 @@ void RedChannelClient::send_ping() void RedChannelClient::send_empty_msg(RedPipeItem *base) { - RedEmptyMsgPipeItem *msg_pipe_item = SPICE_UPCAST(RedEmptyMsgPipeItem, base); + RedEmptyMsgPipeItem *msg_pipe_item = static_cast<RedEmptyMsgPipeItem*>(base); init_send_data(msg_pipe_item->msg); begin_send_message(); @@ -512,7 +512,7 @@ void RedChannelClient::send_any_item(RedPipeItem *item) send_ping(); break; case RED_PIPE_ITEM_TYPE_MARKER: - SPICE_UPCAST(MarkerPipeItem, item)->item_sent = true; + static_cast<MarkerPipeItem*>(item)->item_sent = true; break; default: send_item(item); @@ -1428,19 +1428,17 @@ void RedChannelClient::pipe_add_tail(RedPipeItem *item) void RedChannelClient::pipe_add_type(int pipe_item_type) { - RedPipeItem *item = g_new(RedPipeItem, 1); + RedPipeItem *item = new RedPipeItem(pipe_item_type); - red_pipe_item_init(item, pipe_item_type); pipe_add(item); } RedPipeItem *RedChannelClient::new_empty_msg(int msg_type) { - RedEmptyMsgPipeItem *item = g_new(RedEmptyMsgPipeItem, 1); + RedEmptyMsgPipeItem *item = new RedEmptyMsgPipeItem(RED_PIPE_ITEM_TYPE_EMPTY_MSG); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_EMPTY_MSG); item->msg = msg_type; - return &item->base; + return item; } void RedChannelClient::pipe_add_empty_msg(int msg_type) @@ -1578,12 +1576,11 @@ bool RedChannelClient::wait_pipe_item_sent(GList *item_pos, int64_t timeout) end_time = UINT64_MAX; } - MarkerPipeItem *mark_item = g_new0(MarkerPipeItem, 1); + MarkerPipeItem *mark_item = new MarkerPipeItem(RED_PIPE_ITEM_TYPE_MARKER); - red_pipe_item_init(&mark_item->base, RED_PIPE_ITEM_TYPE_MARKER); mark_item->item_sent = false; - red_pipe_item_ref(&mark_item->base); - pipe_add_before_pos(&mark_item->base, item_pos); + red_pipe_item_ref(mark_item); + pipe_add_before_pos(mark_item, item_pos); for (;;) { receive(); @@ -1596,7 +1593,7 @@ bool RedChannelClient::wait_pipe_item_sent(GList *item_pos, int64_t timeout) } item_sent = mark_item->item_sent; - red_pipe_item_unref(&mark_item->base); + red_pipe_item_unref(mark_item); if (!item_sent) { // still on the queue diff --git a/server/red-channel.cpp b/server/red-channel.cpp index cfe2e606..bedb323a 100644 --- a/server/red-channel.cpp +++ b/server/red-channel.cpp @@ -280,9 +280,7 @@ void RedChannel::pipes_add(RedPipeItem *item) void RedChannel::pipes_add_type(int pipe_item_type) { - RedPipeItem *item = g_new(RedPipeItem, 1); - - red_pipe_item_init(item, pipe_item_type); + RedPipeItem *item = new RedPipeItem(pipe_item_type); pipes_add(item); } diff --git a/server/red-pipe-item.cpp b/server/red-pipe-item.cpp index 9d1ff8c4..1aedd700 100644 --- a/server/red-pipe-item.cpp +++ b/server/red-pipe-item.cpp @@ -20,31 +20,25 @@ #include "red-channel.h" #include "red-pipe-item.h" -RedPipeItem *red_pipe_item_ref(RedPipeItem *item) +RedPipeItem::RedPipeItem(int init_type): + type(init_type) { - g_return_val_if_fail(item->refcount > 0, NULL); - - g_atomic_int_inc(&item->refcount); - - return item; + // compatibility with no shared_ptr reference counting + shared_ptr_add_ref(this); } -void red_pipe_item_unref(RedPipeItem *item) +RedPipeItem *red_pipe_item_ref(RedPipeItem *item) { - g_return_if_fail(item->refcount > 0); + // this call should be replaced by shared_ptr instead + shared_ptr_add_ref(item); - if (g_atomic_int_dec_and_test(&item->refcount)) { - item->free_func(item); - } + return item; } -void red_pipe_item_init_full(RedPipeItem *item, - gint type, - red_pipe_item_free_t *free_func) +void red_pipe_item_unref(RedPipeItem *item) { - item->type = type; - item->refcount = 1; - item->free_func = free_func ? free_func : (red_pipe_item_free_t *)g_free; + // this call should be replaced by shared_ptr instead + shared_ptr_unref(item); } static void marshaller_unref_pipe_item(uint8_t *, void *opaque) diff --git a/server/red-pipe-item.h b/server/red-pipe-item.h index 5d81aacb..2bad0d8e 100644 --- a/server/red-pipe-item.h +++ b/server/red-pipe-item.h @@ -16,40 +16,57 @@ License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +/** + * @file red-pipe-item.h + * Generic declaration for objects contained in RedChannelClient pipe. + */ #ifndef RED_PIPE_ITEM_H_ #define RED_PIPE_ITEM_H_ -#include <stddef.h> -#include <inttypes.h> - -#include "common/marshaller.h" +#include "red-common.h" +#include "utils.hpp" #include "push-visibility.h" -typedef struct RedPipeItem RedPipeItem; - -typedef void red_pipe_item_free_t(RedPipeItem *item); - -struct RedPipeItem { - int type; +/** + * Base class for objects contained in RedChannelClient pipe + */ +struct RedPipeItem: public red::shared_ptr_counted +{ + SPICE_CXX_GLIB_ALLOCATOR + void *operator new(size_t len, void *p) + { + return p; + } + + /** + * Allows to allocate a pipe item with additional space at the end. + * + * Used with structures like + * @code{.cpp} + * struct NameItem: public RedPipeItem { + * ... + * char name[]; + * } + * ... + * auto name_item = red::shared_ptr<NameItem>(new (6) NameItem(...)); + * strcpy(name_item->name, "hello"); + * @endcode + */ + void *operator new(size_t size, size_t additional) + { + return g_malloc(size + additional); + } + + RedPipeItem(int type); + const int type; void add_to_marshaller(SpiceMarshaller *m, uint8_t *data, size_t size); - - /* private */ - int refcount; - - red_pipe_item_free_t *free_func; }; -void red_pipe_item_init_full(RedPipeItem *item, int type, red_pipe_item_free_t free_func); RedPipeItem *red_pipe_item_ref(RedPipeItem *item); void red_pipe_item_unref(RedPipeItem *item); -static inline void red_pipe_item_init(RedPipeItem *item, int type) -{ - red_pipe_item_init_full(item, type, NULL); -} - #include "pop-visibility.h" #endif /* RED_PIPE_ITEM_H_ */ diff --git a/server/reds.cpp b/server/reds.cpp index a4d4e837..900dbe73 100644 --- a/server/reds.cpp +++ b/server/reds.cpp @@ -153,13 +153,15 @@ struct ChannelSecurityOptions { ChannelSecurityOptions *next; }; -typedef struct RedVDIReadBuf { - RedPipeItem base; +struct RedVDIReadBuf final: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~RedVDIReadBuf(); + RedCharDeviceVDIPort *dev; int len; uint8_t data[SPICE_AGENT_MAX_DATA_SIZE]; -} RedVDIReadBuf; +}; typedef enum { VDI_PORT_READ_STATE_READ_HEADER, @@ -238,7 +240,6 @@ 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_pipe_item_free_t vdi_port_read_buf_free; static ChannelSecurityOptions *reds_find_channel_security(RedsState *reds, int id) { @@ -405,7 +406,7 @@ static void reds_reset_vdp(RedsState *reds) 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->base); + red_pipe_item_unref(dev->priv->current_read_buf); dev->priv->current_read_buf = NULL; } /* Reset read filter to start with clean state when the agent reconnects */ @@ -658,7 +659,7 @@ static void reds_agent_remove(RedsState *reds) static void vdi_port_read_buf_release(uint8_t *data, void *opaque) { RedVDIReadBuf *read_buf = (RedVDIReadBuf *)opaque; - red_pipe_item_unref(&read_buf->base); + red_pipe_item_unref(read_buf); } /* @@ -681,15 +682,25 @@ static AgentMsgFilterResult vdi_port_read_buf_process(RedCharDeviceVDIPort *dev, } } -static RedVDIReadBuf *vdi_read_buf_new(RedCharDeviceVDIPort *dev) +RedVDIReadBuf::~RedVDIReadBuf() { - RedVDIReadBuf *buf = g_new(RedVDIReadBuf, 1); + dev->priv->num_read_buf--; + /* read_one_msg_from_vdi_port may have never completed because we + reached buffer limit. So we call it again so it can complete its work if + necessary. Note that since we can be called from red_char_device_wakeup + this can cause recursion, but we have protection for that */ + if (dev->priv->agent_attached) { + dev->wakeup(); + } +} + +static RedVDIReadBuf *vdi_read_buf_new(RedCharDeviceVDIPort *dev) +{ /* Bogus pipe item type, we only need the RingItem and refcounting * from the base class and are not going to use the type */ - red_pipe_item_init_full(&buf->base, -1, - vdi_port_read_buf_free); + RedVDIReadBuf *buf = new RedVDIReadBuf(-1); buf->dev = dev; buf->len = 0; return buf; @@ -705,23 +716,6 @@ static RedVDIReadBuf *vdi_port_get_read_buf(RedCharDeviceVDIPort *dev) return vdi_read_buf_new(dev); } -static void vdi_port_read_buf_free(RedPipeItem *base) -{ - RedVDIReadBuf *buf = SPICE_UPCAST(RedVDIReadBuf, base); - - g_warn_if_fail(buf->base.refcount == 0); - buf->dev->priv->num_read_buf--; - - /* read_one_msg_from_vdi_port may have never completed because we - reached buffer limit. So we call it again so it can complete its work if - necessary. Note that since we can be called from red_char_device_wakeup - this can cause recursion, but we have protection for that */ - if (buf->dev->priv->agent_attached) { - buf->dev->wakeup(); - } - g_free(buf); -} - /* certain agent capabilities can be overridden and disabled in the server. In these cases, unset * these capabilities before sending them on to the client */ static void reds_adjust_agent_capabilities(RedsState *reds, VDAgentMessage *message) @@ -807,14 +801,14 @@ RedCharDeviceVDIPort::read_one_msg_from_device() 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->base; + return dispatch_buf; case AGENT_MSG_FILTER_PROTO_ERROR: reds_agent_remove(reds); /* fall through */ case AGENT_MSG_FILTER_MONITORS_CONFIG: /* fall through */ case AGENT_MSG_FILTER_DISCARD: - red_pipe_item_unref(&dispatch_buf->base); + red_pipe_item_unref(dispatch_buf); } } } /* END switch */ @@ -911,7 +905,7 @@ void reds_send_device_display_info(RedsState *reds) void RedCharDeviceVDIPort::send_msg_to_client(RedPipeItem *msg, RedCharDeviceClientOpaque *opaque) { RedClient *client = (RedClient *) opaque; - RedVDIReadBuf *agent_data_buf = (RedVDIReadBuf *)msg; + RedVDIReadBuf *agent_data_buf = static_cast<RedVDIReadBuf*>(msg); red_pipe_item_ref(msg); client->get_main()->push_agent_data(agent_data_buf->data, @@ -1283,7 +1277,7 @@ 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->base); + red_pipe_item_unref(read_buf); } spice_assert(agent_dev->priv->receive_len); @@ -4472,7 +4466,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->base); + red_pipe_item_unref(priv->current_read_buf); priv->current_read_buf = NULL; } g_free(priv->mig_data); diff --git a/server/smartcard-channel-client.cpp b/server/smartcard-channel-client.cpp index 40d98989..7a8166d7 100644 --- a/server/smartcard-channel-client.cpp +++ b/server/smartcard-channel-client.cpp @@ -32,11 +32,11 @@ struct SmartCardChannelClientPrivate bool msg_in_write_buf = false; }; -typedef struct RedErrorItem { - RedPipeItem base; +struct RedErrorItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; VSCMsgHeader vheader; VSCMsgError error; -} RedErrorItem; +}; SmartCardChannelClient::SmartCardChannelClient(RedChannel *channel, RedClient *client, @@ -129,7 +129,7 @@ void smartcard_channel_client_send_data(RedChannelClient *rcc, void smartcard_channel_client_send_error(RedChannelClient *rcc, SpiceMarshaller *m, RedPipeItem *item) { - RedErrorItem* error_item = SPICE_UPCAST(RedErrorItem, item); + RedErrorItem* error_item = static_cast<RedErrorItem*>(item); smartcard_channel_client_send_data(rcc, m, item, &error_item->vheader); } @@ -138,15 +138,13 @@ static void smartcard_channel_client_push_error(RedChannelClient *rcc, uint32_t reader_id, VSCErrorCode error) { - RedErrorItem *error_item = g_new0(RedErrorItem, 1); - - red_pipe_item_init(&error_item->base, RED_PIPE_ITEM_TYPE_ERROR); + RedErrorItem *error_item = new RedErrorItem(RED_PIPE_ITEM_TYPE_ERROR); error_item->vheader.reader_id = reader_id; error_item->vheader.type = VSC_Error; error_item->vheader.length = sizeof(error_item->error); error_item->error.code = error; - rcc->pipe_add_push(&error_item->base); + rcc->pipe_add_push(error_item); } static void smartcard_channel_client_add_reader(SmartCardChannelClient *scc) diff --git a/server/smartcard.cpp b/server/smartcard.cpp index 4af60c63..39d46da7 100644 --- a/server/smartcard.cpp +++ b/server/smartcard.cpp @@ -67,11 +67,11 @@ struct RedCharDeviceSmartcardPrivate { int reader_added; // has reader_add been sent to the device }; -typedef struct RedMsgItem { - RedPipeItem base; - +struct RedMsgItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~RedMsgItem(); VSCMsgHeader* vheader; -} RedMsgItem; +}; static RedMsgItem *smartcard_new_vsc_msg_item(unsigned int reader_id, const VSCMsgHeader *vheader); @@ -138,9 +138,9 @@ RedCharDeviceSmartcard::read_one_msg_from_device() dev->priv->buf_used = remaining; if (msg_to_client) { if (dev->priv->scc) { - dev->priv->scc->pipe_add_push(&msg_to_client->base); + dev->priv->scc->pipe_add_push(msg_to_client); } else { - red_pipe_item_unref(&msg_to_client->base); + red_pipe_item_unref(msg_to_client); } } } @@ -338,7 +338,7 @@ SmartCardChannelClient* smartcard_char_device_get_client(RedCharDeviceSmartcard static void smartcard_channel_send_msg(RedChannelClient *rcc, SpiceMarshaller *m, RedPipeItem *item) { - RedMsgItem* msg_item = SPICE_UPCAST(RedMsgItem, item); + RedMsgItem* msg_item = static_cast<RedMsgItem*>(item); smartcard_channel_client_send_data(rcc, m, item, msg_item->vheader); } @@ -390,19 +390,15 @@ void SmartCardChannelClient::send_item(RedPipeItem *item) begin_send_message(); } -static void smartcard_free_vsc_msg_item(RedPipeItem *base) +RedMsgItem::~RedMsgItem() { - RedMsgItem *item = SPICE_UPCAST(RedMsgItem, base); - g_free(item->vheader); - g_free(item); + g_free(vheader); } static RedMsgItem *smartcard_new_vsc_msg_item(unsigned int reader_id, const VSCMsgHeader *vheader) { - RedMsgItem *msg_item = g_new0(RedMsgItem, 1); + RedMsgItem *msg_item = new RedMsgItem(RED_PIPE_ITEM_TYPE_SMARTCARD_DATA); - red_pipe_item_init_full(&msg_item->base, RED_PIPE_ITEM_TYPE_SMARTCARD_DATA, - smartcard_free_vsc_msg_item); msg_item->vheader = (VSCMsgHeader*) g_memdup(vheader, sizeof(*vheader) + vheader->length); /* We patch the reader_id, since the device only knows about itself, and * we know about the sum of readers. */ diff --git a/server/sound.cpp b/server/sound.cpp index bfcf5124..a35d6753 100644 --- a/server/sound.cpp +++ b/server/sound.cpp @@ -74,11 +74,17 @@ struct RecordChannelClient; struct AudioFrame; struct AudioFrameContainer; -struct PersistentPipeItem: public RedPipeItem +/* This pipe item is never deleted and added to the queue when messages + * have to be sent. + * This is used to have a simple item in RedChannelClient queue but to send + * multiple messages in a row if possible. + * During realtime sound transmission you usually don't want to queue too + * much data or having retransmission preferring instead loosing some + * samples. + */ +struct PersistentPipeItem final: public RedPipeItem { PersistentPipeItem(); -private: - static void item_free(RedPipeItem *item); }; /* Connects an audio client to a Spice client */ @@ -610,21 +616,8 @@ static bool playback_send_mode(PlaybackChannelClient *playback_client) return true; } -PersistentPipeItem::PersistentPipeItem() -{ - red_pipe_item_init_full(this, RED_PIPE_ITEM_PERSISTENT, item_free); -} - -/* This function is called when the "persistent" item is removed from the - * queue. Note that there is not free call as the item is allocated into - * SndChannelClient. - * This is used to have a simple item in RedChannelClient queue but to send - * multiple messages in a row if possible. - * During realtime sound transmission you usually don't want to queue too - * much data or having retransmission preferring instead loosing some - * samples. - */ -void PersistentPipeItem::item_free(RedPipeItem *item) +PersistentPipeItem::PersistentPipeItem(): + RedPipeItem(RED_PIPE_ITEM_PERSISTENT) { } diff --git a/server/spicevmc.cpp b/server/spicevmc.cpp index bb7a0216..6eb34ae8 100644 --- a/server/spicevmc.cpp +++ b/server/spicevmc.cpp @@ -45,15 +45,15 @@ struct RedVmcChannel; class VmcChannelClient; -typedef struct RedVmcPipeItem { - RedPipeItem base; +struct RedVmcPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; SpiceDataCompressionType type; uint32_t uncompressed_data_size; /* writes which don't fit this will get split, this is not a problem */ uint8_t buf[BUF_SIZE]; uint32_t buf_used; -} RedVmcPipeItem; +}; struct RedCharDeviceSpiceVmc: public RedCharDevice { @@ -158,7 +158,7 @@ RedVmcChannel::~RedVmcChannel() { RedCharDevice::write_buffer_release(chardev, &recv_from_client_buf); if (pipe_item) { - red_pipe_item_unref(&pipe_item->base); + red_pipe_item_unref(pipe_item); } } @@ -183,16 +183,19 @@ static red::shared_ptr<RedVmcChannel> red_vmc_channel_new(RedsState *reds, uint8 return red::make_shared<RedVmcChannel>(reds, channel_type, id); } -typedef struct RedPortInitPipeItem { - RedPipeItem base; +struct RedPortInitPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~RedPortInitPipeItem(); + char* name; uint8_t opened; -} RedPortInitPipeItem; +}; + +struct RedPortEventPipeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; -typedef struct RedPortEventPipeItem { - RedPipeItem base; uint8_t event; -} RedPortEventPipeItem; +}; enum { RED_PIPE_ITEM_TYPE_SPICEVMC_DATA = RED_PIPE_ITEM_TYPE_CHANNEL_BASE, @@ -225,8 +228,7 @@ static RedVmcPipeItem* try_compress_lz4(RedVmcChannel *channel, int n, RedVmcPip /* Client doesn't have compression cap - data will not be compressed */ return NULL; } - msg_item_compressed = g_new0(RedVmcPipeItem, 1); - red_pipe_item_init(&msg_item_compressed->base, RED_PIPE_ITEM_TYPE_SPICEVMC_DATA); + msg_item_compressed = new RedVmcPipeItem(RED_PIPE_ITEM_TYPE_SPICEVMC_DATA); compressed_data_count = LZ4_compress_default((char*)&msg_item->buf, (char*)&msg_item_compressed->buf, n, @@ -258,9 +260,8 @@ RedPipeItem* RedCharDeviceSpiceVmc::read_one_msg_from_device() } if (!channel->pipe_item) { - msg_item = g_new0(RedVmcPipeItem, 1); + msg_item = new RedVmcPipeItem(RED_PIPE_ITEM_TYPE_SPICEVMC_DATA); msg_item->type = SPICE_DATA_COMPRESSION_TYPE_NONE; - red_pipe_item_init(&msg_item->base, RED_PIPE_ITEM_TYPE_SPICEVMC_DATA); } else { spice_assert(channel->pipe_item->buf_used == 0); msg_item = channel->pipe_item; @@ -289,33 +290,28 @@ RedPipeItem* RedCharDeviceSpiceVmc::read_one_msg_from_device() return NULL; } -static void red_port_init_item_free(struct RedPipeItem *base) +RedPortInitPipeItem::~RedPortInitPipeItem() { - RedPortInitPipeItem *item = SPICE_UPCAST(RedPortInitPipeItem, base); - - g_free(item->name); - g_free(item); + g_free(name); } static void spicevmc_port_send_init(VmcChannelClient *rcc) { RedVmcChannel *channel = rcc->get_channel(); SpiceCharDeviceInstance *sin = channel->chardev_sin; - RedPortInitPipeItem *item = g_new(RedPortInitPipeItem, 1); + RedPortInitPipeItem *item = new RedPortInitPipeItem(RED_PIPE_ITEM_TYPE_PORT_INIT); - red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_PORT_INIT, red_port_init_item_free); item->name = g_strdup(sin->portname); item->opened = channel->port_opened; - rcc->pipe_add_push(&item->base); + rcc->pipe_add_push(item); } static void spicevmc_port_send_event(RedChannelClient *rcc, uint8_t event) { - RedPortEventPipeItem *item = g_new(RedPortEventPipeItem, 1); + RedPortEventPipeItem *item = new RedPortEventPipeItem(RED_PIPE_ITEM_TYPE_PORT_EVENT); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_PORT_EVENT); item->event = event; - rcc->pipe_add_push(&item->base); + rcc->pipe_add_push(item); } void RedCharDeviceSpiceVmc::remove_client(RedCharDeviceClientOpaque *opaque) @@ -510,14 +506,14 @@ static void spicevmc_red_channel_queue_data(RedVmcChannel *channel, RedVmcPipeItem *item) { channel->queued_data += item->buf_used; - channel->rcc->pipe_add_push(&item->base); + channel->rcc->pipe_add_push(item); } static void spicevmc_red_channel_send_data(VmcChannelClient *rcc, SpiceMarshaller *m, RedPipeItem *item) { - RedVmcPipeItem *i = SPICE_UPCAST(RedVmcPipeItem, item); + RedVmcPipeItem *i = static_cast<RedVmcPipeItem*>(item); RedVmcChannel *channel = rcc->get_channel(); /* for compatibility send using not compressed data message */ @@ -561,7 +557,7 @@ static void spicevmc_red_channel_send_port_init(RedChannelClient *rcc, SpiceMarshaller *m, RedPipeItem *item) { - RedPortInitPipeItem *i = SPICE_UPCAST(RedPortInitPipeItem, item); + RedPortInitPipeItem *i = static_cast<RedPortInitPipeItem*>(item); SpiceMsgPortInit init; rcc->init_send_data(SPICE_MSG_PORT_INIT); @@ -575,7 +571,7 @@ static void spicevmc_red_channel_send_port_event(RedChannelClient *rcc, SpiceMarshaller *m, RedPipeItem *item) { - RedPortEventPipeItem *i = SPICE_UPCAST(RedPortEventPipeItem, item); + RedPortEventPipeItem *i = static_cast<RedPortEventPipeItem*>(item); SpiceMsgPortEvent event; rcc->init_send_data(SPICE_MSG_PORT_EVENT); diff --git a/server/stream-channel.cpp b/server/stream-channel.cpp index bcccbe5d..9fe527c4 100644 --- a/server/stream-channel.cpp +++ b/server/stream-channel.cpp @@ -67,17 +67,19 @@ enum { RED_PIPE_ITEM_TYPE_MONITORS_CONFIG, }; -typedef struct StreamCreateItem { - RedPipeItem base; +struct StreamCreateItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; SpiceMsgDisplayStreamCreate stream_create; -} StreamCreateItem; +}; + +struct StreamDataItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~StreamDataItem(); -typedef struct StreamDataItem { - RedPipeItem base; StreamChannel *channel; // NOTE: this must be the last field in the structure SpiceMsgDisplayStreamData data; -} StreamDataItem; +}; #define PRIMARY_SURFACE_ID 0 @@ -210,7 +212,7 @@ void StreamChannelClient::send_item(RedPipeItem *pipe_item) break; } case RED_PIPE_ITEM_TYPE_STREAM_CREATE: { - StreamCreateItem *item = SPICE_UPCAST(StreamCreateItem, pipe_item); + StreamCreateItem *item = static_cast<StreamCreateItem*>(pipe_item); stream_id = item->stream_create.id; init_send_data(SPICE_MSG_DISPLAY_STREAM_CREATE); spice_marshall_msg_display_stream_create(m, &item->stream_create); @@ -231,7 +233,7 @@ void StreamChannelClient::send_item(RedPipeItem *pipe_item) break; } case RED_PIPE_ITEM_TYPE_STREAM_DATA: { - StreamDataItem *item = SPICE_UPCAST(StreamDataItem, pipe_item); + StreamDataItem *item = static_cast<StreamDataItem*>(pipe_item); init_send_data(SPICE_MSG_DISPLAY_STREAM_DATA); spice_marshall_msg_display_stream_data(m, &item->data); pipe_item->add_to_marshaller(m, item->data.data, item->data.data_size); @@ -424,8 +426,7 @@ StreamChannel::change_format(const StreamMsgFormat *fmt) stream_id = (stream_id + 1) % NUM_STREAMS; // send create stream - StreamCreateItem *item = g_new0(StreamCreateItem, 1); - red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_STREAM_CREATE); + StreamCreateItem *item = new StreamCreateItem(RED_PIPE_ITEM_TYPE_STREAM_CREATE); item->stream_create.id = stream_id; item->stream_create.flags = SPICE_STREAM_FLAGS_TOP_DOWN; item->stream_create.codec_type = fmt->codec; @@ -435,7 +436,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->base); + pipes_add(item); // activate stream report if possible pipes_add_type(RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT); @@ -451,14 +452,9 @@ StreamChannel::update_queue_stat(int32_t num_diff, int32_t size_diff) } } -void -StreamChannel::data_item_free(RedPipeItem *base) +StreamDataItem::~StreamDataItem() { - StreamDataItem *pipe_item = SPICE_UPCAST(StreamDataItem, base); - - pipe_item->channel->update_queue_stat(-1, -pipe_item->data.data_size); - - g_free(pipe_item); + channel->update_queue_stat(-1, -data.data_size); } void @@ -471,9 +467,7 @@ StreamChannel::send_data(const void *data, size_t size, uint32_t mm_time) return; } - StreamDataItem *item = (StreamDataItem*) g_malloc(sizeof(*item) + size); - red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_STREAM_DATA, - data_item_free); + StreamDataItem *item = new (size) StreamDataItem(RED_PIPE_ITEM_TYPE_STREAM_DATA); item->data.base.id = stream_id; item->data.base.multi_media_time = mm_time; item->data.data_size = size; @@ -481,7 +475,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->base); + pipes_add(item); } void diff --git a/server/stream-channel.h b/server/stream-channel.h index 6b4c76e3..9a65460f 100644 --- a/server/stream-channel.h +++ b/server/stream-channel.h @@ -50,10 +50,12 @@ struct StreamQueueStat { typedef void (*stream_channel_queue_stat_proc)(void *opaque, const StreamQueueStat *stats, StreamChannel *channel); +struct StreamDataItem; struct StreamChannelClient; struct StreamChannel final: public RedChannel { friend struct StreamChannelClient; + friend struct StreamDataItem; StreamChannel(RedsState *reds, uint32_t id); /** @@ -73,7 +75,6 @@ private: inline void update_queue_stat(int32_t num_diff, int32_t size_diff); void request_new_stream(StreamMsgStartStop *start); - static void data_item_free(RedPipeItem *base); /* current video stream id, <0 if not initialized or * we are not sending a stream */ diff --git a/server/video-stream.cpp b/server/video-stream.cpp index 9a6df289..02d01e32 100644 --- a/server/video-stream.cpp +++ b/server/video-stream.cpp @@ -64,24 +64,20 @@ static void video_stream_agent_stats_print(VideoStreamAgent *agent) #endif } -static void video_stream_create_destroy_item_release(RedPipeItem *base) +StreamCreateDestroyItem::~StreamCreateDestroyItem() { - StreamCreateDestroyItem *item = SPICE_UPCAST(StreamCreateDestroyItem, base); - DisplayChannel *display = DCC_TO_DC(item->agent->dcc); - video_stream_agent_unref(display, item->agent); - g_free(item); + DisplayChannel *display = DCC_TO_DC(agent->dcc); + video_stream_agent_unref(display, agent); } static RedPipeItem *video_stream_create_destroy_item_new(VideoStreamAgent *agent, - gint type) + int type) { - StreamCreateDestroyItem *item = g_new0(StreamCreateDestroyItem, 1); + StreamCreateDestroyItem *item = new StreamCreateDestroyItem(type); - red_pipe_item_init_full(&item->base, type, - video_stream_create_destroy_item_release); agent->stream->refs++; item->agent = agent; - return &item->base; + return item; } static RedPipeItem *video_stream_create_item_new(VideoStreamAgent *agent) @@ -163,24 +159,17 @@ void video_stream_agent_unref(DisplayChannel *display, VideoStreamAgent *agent) video_stream_unref(display, agent->stream); } -static void video_stream_clip_item_free(RedPipeItem *base) +VideoStreamClipItem::~VideoStreamClipItem() { - g_return_if_fail(base != NULL); - VideoStreamClipItem *item = SPICE_UPCAST(VideoStreamClipItem, base); - DisplayChannel *display = DCC_TO_DC(item->stream_agent->dcc); - - g_return_if_fail(item->base.refcount == 0); + DisplayChannel *display = DCC_TO_DC(stream_agent->dcc); - video_stream_agent_unref(display, item->stream_agent); - g_free(item->rects); - g_free(item); + video_stream_agent_unref(display, stream_agent); + g_free(rects); } VideoStreamClipItem *video_stream_clip_item_new(VideoStreamAgent *agent) { - VideoStreamClipItem *item = g_new(VideoStreamClipItem, 1); - red_pipe_item_init_full(&item->base, RED_PIPE_ITEM_TYPE_STREAM_CLIP, - video_stream_clip_item_free); + VideoStreamClipItem *item = new VideoStreamClipItem(RED_PIPE_ITEM_TYPE_STREAM_CLIP); item->stream_agent = agent; agent->stream->refs++; @@ -364,7 +353,7 @@ static void before_reattach_stream(DisplayChannel *display, dcc = dpi->dcc; agent = dcc_get_video_stream_agent(dcc, index); - if (dcc->pipe_item_is_linked(&dpi->base)) { + if (dcc->pipe_item_is_linked(dpi)) { #ifdef STREAM_STATS agent->stats.num_drops_pipe++; #endif @@ -784,14 +773,13 @@ 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 = g_new0(RedStreamActivateReportItem, 1); + RedStreamActivateReportItem *report_pipe_item = + new RedStreamActivateReportItem(RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT); agent->report_id = rand(); - red_pipe_item_init(&report_pipe_item->base, - RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT); report_pipe_item->stream_id = stream_id; report_pipe_item->report_id = agent->report_id; - dcc->pipe_add(&report_pipe_item->base); + dcc->pipe_add(report_pipe_item); } #ifdef STREAM_STATS memset(&agent->stats, 0, sizeof(StreamStats)); @@ -812,17 +800,10 @@ void video_stream_agent_stop(VideoStreamAgent *agent) } } -static void red_upgrade_item_free(RedPipeItem *base) +RedUpgradeItem::~RedUpgradeItem() { - g_return_if_fail(base != NULL); - - RedUpgradeItem *item = SPICE_UPCAST(RedUpgradeItem, base); - - g_return_if_fail(item->base.refcount == 0); - - drawable_unref(item->drawable); - g_free(item->rects); - g_free(item); + drawable_unref(drawable); + g_free(rects); } /* @@ -861,9 +842,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 = g_new(RedUpgradeItem, 1); - red_pipe_item_init_full(&upgrade_item->base, RED_PIPE_ITEM_TYPE_UPGRADE, - red_upgrade_item_free); + upgrade_item = new 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); @@ -871,7 +850,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->base); + dcc->pipe_add(upgrade_item); } else { SpiceRect upgrade_area; diff --git a/server/video-stream.h b/server/video-stream.h index b12e24a0..e35d740f 100644 --- a/server/video-stream.h +++ b/server/video-stream.h @@ -49,17 +49,18 @@ typedef struct VideoStream VideoStream; /* This item is used to send a full quality image (lossless) of the area where the stream was. * This to avoid the artifacts due to the lossy compression. */ -typedef struct RedUpgradeItem { - RedPipeItem base; +struct RedUpgradeItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~RedUpgradeItem(); Drawable *drawable; SpiceClipRects *rects; -} RedUpgradeItem; +}; -typedef struct RedStreamActivateReportItem { - RedPipeItem base; +struct RedStreamActivateReportItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; uint32_t stream_id; uint32_t report_id; -} RedStreamActivateReportItem; +}; #ifdef STREAM_STATS typedef struct StreamStats { @@ -95,19 +96,21 @@ typedef struct VideoStreamAgent { #endif } VideoStreamAgent; -typedef struct VideoStreamClipItem { - RedPipeItem base; +struct VideoStreamClipItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~VideoStreamClipItem(); VideoStreamAgent *stream_agent; int clip_type; SpiceClipRects *rects; -} VideoStreamClipItem; +}; VideoStreamClipItem *video_stream_clip_item_new(VideoStreamAgent *agent); -typedef struct StreamCreateDestroyItem { - RedPipeItem base; +struct StreamCreateDestroyItem: public RedPipeItem { + using RedPipeItem::RedPipeItem; + ~StreamCreateDestroyItem(); VideoStreamAgent *agent; -} StreamCreateDestroyItem; +}; typedef struct ItemTrace { red_time_t time; |