[PATCH 3/4] compositor-drm: Free output on error in create_output_for_connector
David Herrmann
dh.herrmann at googlemail.com
Thu Dec 8 08:05:45 PST 2011
We currently simply return -1 on error in create_output_for_connector. This
correctly frees the output and all modes when we fail to avoid memory leaks.
Signed-off-by: David Herrmann <dh.herrmann at googlemail.com>
---
compositor/compositor-drm.c | 34 +++++++++++++++++++++++++++-------
1 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/compositor/compositor-drm.c b/compositor/compositor-drm.c
index 1f5e028..2291f48 100644
--- a/compositor/compositor-drm.c
+++ b/compositor/compositor-drm.c
@@ -427,7 +427,7 @@ create_output_for_connector(struct drm_compositor *ec,
int x, int y)
{
struct drm_output *output;
- struct drm_mode *drm_mode;
+ struct drm_mode *drm_mode, *next;
drmModeEncoder *encoder;
int i, ret;
unsigned handle, stride;
@@ -467,11 +467,19 @@ create_output_for_connector(struct drm_compositor *ec,
ec->connector_allocator |= (1 << output->connector_id);
output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
+ drmModeFreeEncoder(encoder);
+
+ for (i = 0; i < connector->count_modes; i++) {
+ ret = drm_output_add_mode(output, &connector->modes[i]);
+ if (ret)
+ goto err_free;
+ }
- for (i = 0; i < connector->count_modes; i++)
- drm_output_add_mode(output, &connector->modes[i]);
- if (connector->count_modes == 0)
- drm_output_add_mode(output, &builtin_1024x768);
+ if (connector->count_modes == 0) {
+ ret = drm_output_add_mode(output, &builtin_1024x768);
+ if (ret)
+ goto err_free;
+ }
drm_mode = container_of(output->base.mode_list.next,
struct drm_mode, base.link);
@@ -479,8 +487,6 @@ create_output_for_connector(struct drm_compositor *ec,
drm_mode->base.flags =
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
- drmModeFreeEncoder(encoder);
-
glGenRenderbuffers(2, output->rbo);
for (i = 0; i < 2; i++) {
glBindRenderbuffer(GL_RENDERBUFFER, output->rbo[i]);
@@ -541,6 +547,20 @@ create_output_for_connector(struct drm_compositor *ec,
output->base.destroy = drm_output_destroy;
return 0;
+
+err_free:
+ wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
+ base.link) {
+ wl_list_remove(&drm_mode->base.link);
+ free(drm_mode);
+ }
+
+ drmModeFreeCrtc(output->original_crtc);
+ ec->crtc_allocator &= ~(1 << output->crtc_id);
+ ec->connector_allocator &= ~(1 << output->connector_id);
+
+ free(output);
+ return -1;
}
static int
--
1.7.8
More information about the wayland-devel
mailing list