summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <ssp@redhat.com>2012-02-09 16:54:29 -0500
committerSøren Sandmann <ssp@redhat.com>2012-02-09 16:54:29 -0500
commit96349ebb43e7de49b6b561b79d6fff5ada7aa4c7 (patch)
treea167ad45e1fc8bfe22c99965fcfccccfd8b0cb10
parentc5ab0b538bd437e5e4aa86678d12a676c6edd1e8 (diff)
Don't leak the surface when we run out of video memory.
Running out of video memory would cause send_create_surface() to return NULL without putting the allocated surface back on the free list. Fix this by not allocating the surface until after the video memory is allocated, and, if surface allocation fails, freeing the video memory.
-rw-r--r--src/qxl_surface.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 5cb7ec1..06bee09 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -589,22 +589,10 @@ surface_send_create (surface_cache_t *cache,
int n_attempts = 0;
qxl_screen_t *qxl = cache->qxl;
qxl_surface_t *surface;
+ void *address;
get_formats (bpp, &format, &pformat);
-retry:
- surface = surface_get_from_free_list (cache);
- if (!surface)
- {
- if (!qxl_handle_oom (cache->qxl))
- {
- ErrorF (" Out of surfaces\n");
- return NULL;
- }
- else
- goto retry;
- }
-
width = align (width);
height = align (height);
@@ -616,9 +604,9 @@ retry:
*/
qxl_garbage_collect (cache->qxl);
retry2:
- surface->address = qxl_alloc (qxl->surf_mem, stride * height + stride);
+ address = qxl_alloc (qxl->surf_mem, stride * height + stride);
- if (!surface->address)
+ if (!address)
{
ErrorF ("- %dth attempt\n", n_attempts++);
@@ -641,7 +629,22 @@ retry2:
return NULL;
}
- surface->end = (char *)surface->address + stride * height;
+retry:
+ surface = surface_get_from_free_list (cache);
+ if (!surface)
+ {
+ if (!qxl_handle_oom (cache->qxl))
+ {
+ ErrorF (" Out of surfaces\n");
+ qxl_free (qxl->surf_mem, address);
+ return NULL;
+ }
+ else
+ goto retry;
+ }
+
+ surface->address = address;
+ surface->end = (char *)address + stride * height;
cmd = make_surface_cmd (cache, surface->id, QXL_SURFACE_CMD_CREATE);