diff options
author | Søren Sandmann <ssp@redhat.com> | 2012-02-09 16:54:29 -0500 |
---|---|---|
committer | Søren Sandmann <ssp@redhat.com> | 2012-02-09 16:54:29 -0500 |
commit | 96349ebb43e7de49b6b561b79d6fff5ada7aa4c7 (patch) | |
tree | a167ad45e1fc8bfe22c99965fcfccccfd8b0cb10 | |
parent | c5ab0b538bd437e5e4aa86678d12a676c6edd1e8 (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.c | 35 |
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); |