diff options
author | Christophe Fergeau <cfergeau@redhat.com> | 2018-04-10 16:18:11 +0200 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2018-04-23 14:36:39 +0200 |
commit | d961a1bbc1c025d502a2c1495aad8c23fa8548ed (patch) | |
tree | 83b4953f8b77acfdf5d8849c90523ee590418c19 | |
parent | a62892535689e7c62b1b3d2ea3927d52c1c615c5 (diff) |
qxl: Fix guest resources release in red_put_drawable()
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.
-rw-r--r-- | server/red-parse-qxl.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c index a4724f6a..b819df63 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, @@ -1486,7 +1491,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); } @@ -1498,9 +1502,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; } |