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. --- 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 03a3a655a..15413af91 100644 --- a/server/red-parse-qxl.c +++ b/server/red-parse-qxl.c @@ -1008,7 +1008,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; @@ -1018,6 +1018,7 @@ static bool red_get_native_drawable(RedMemSlotInfo *slots, int group_id, if (qxl == NULL) { return false; } + red->qxl = qxl_instance; red->release_info_ext.info = &qxl->release_info; red->release_info_ext.group_id = group_id; @@ -1088,7 +1089,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; @@ -1097,6 +1098,7 @@ static bool red_get_compat_drawable(RedMemSlotInfo *slots, int group_id, if (qxl == NULL) { return false; } + red->qxl = qxl_instance; red->release_info_ext.info = &qxl->release_info; red->release_info_ext.group_id = group_id; @@ -1170,15 +1172,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; } @@ -1230,6 +1232,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, @@ -1481,7 +1486,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); } @@ -1493,9 +1497,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.19.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel