At the moment, we'll unconditionally release the guest QXL resources in red_put_drawable() even if red_get_drawable() failed and did not initialize drawable->release_info_ext properly. This commit only sets RedDrawable::qxl once the guest resource have been successfully retrieved, and only free the guest QXL resources when RedDrawable::qxl is set. Signed-off-by: Christophe Fergeau <cfergeau@xxxxxxxxxx> --- server/red-parse-qxl.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c index a705c0d9d..d03625e43 100644 --- a/server/red-parse-qxl.c +++ b/server/red-parse-qxl.c @@ -1011,7 +1011,7 @@ static void red_put_clip(SpiceClip *red) } } -static bool red_get_native_drawable(RedMemSlotInfo *slots, int group_id, +static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id, RedDrawable *red, QXLPHYSICAL addr, uint32_t flags) { QXLDrawable *qxl; @@ -1022,6 +1022,7 @@ static bool red_get_native_drawable(RedMemSlotInfo *slots, int group_id, if (error) { return false; } + red->qxl = qxl_instance; red->release_info_ext.info = &qxl->release_info; red->release_info_ext.group_id = group_id; @@ -1092,7 +1093,7 @@ static bool red_get_native_drawable(RedMemSlotInfo *slots, int group_id, return true; } -static bool red_get_compat_drawable(RedMemSlotInfo *slots, int group_id, +static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id, RedDrawable *red, QXLPHYSICAL addr, uint32_t flags) { QXLCompatDrawable *qxl; @@ -1102,6 +1103,7 @@ static bool red_get_compat_drawable(RedMemSlotInfo *slots, int group_id, if (error) { return false; } + red->qxl = qxl_instance; red->release_info_ext.info = &qxl->release_info; red->release_info_ext.group_id = group_id; @@ -1175,15 +1177,15 @@ static bool red_get_compat_drawable(RedMemSlotInfo *slots, int group_id, return true; } -static bool red_get_drawable(RedMemSlotInfo *slots, int group_id, +static bool red_get_drawable(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, RedDrawable *red, QXLPHYSICAL addr, uint32_t flags) { bool ret; if (flags & QXL_COMMAND_FLAG_COMPAT) { - ret = red_get_compat_drawable(slots, group_id, red, addr, flags); + ret = red_get_compat_drawable(qxl, slots, group_id, red, addr, flags); } else { - ret = red_get_native_drawable(slots, group_id, red, addr, flags); + ret = red_get_native_drawable(qxl, slots, group_id, red, addr, flags); } return ret; } @@ -1235,6 +1237,9 @@ static void red_put_drawable(RedDrawable *red) red_put_whiteness(&red->u.whiteness); break; } + if (red->qxl != NULL) { + red_qxl_release_resource(red->qxl, red->release_info_ext); + } } bool red_get_update_cmd(RedMemSlotInfo *slots, int group_id, @@ -1492,7 +1497,6 @@ void red_drawable_unref(RedDrawable *red_drawable) if (--red_drawable->refs) { return; } - red_qxl_release_resource(red_drawable->qxl, red_drawable->release_info_ext); red_put_drawable(red_drawable); g_free(red_drawable); } @@ -1504,9 +1508,8 @@ RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots, RedDrawable *red = g_new0(RedDrawable, 1); red->refs = 1; - red->qxl = qxl; - if (!red_get_drawable(slots, group_id, red, addr, flags)) { + if (!red_get_drawable(qxl, slots, group_id, red, addr, flags)) { red_drawable_unref(red); return NULL; } -- 2.14.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel