summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2018-04-10 16:18:11 +0200
committerChristophe Fergeau <cfergeau@redhat.com>2018-04-23 14:36:39 +0200
commitd961a1bbc1c025d502a2c1495aad8c23fa8548ed (patch)
tree83b4953f8b77acfdf5d8849c90523ee590418c19
parenta62892535689e7c62b1b3d2ea3927d52c1c615c5 (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.c19
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;
}