[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