compositor-drm: Free output on error in create_output_for_connector
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@googlemail.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
eb8bed5c73
commit
0f0d54e5c5
@@ -427,7 +427,7 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
int x, int y)
|
int x, int y)
|
||||||
{
|
{
|
||||||
struct drm_output *output;
|
struct drm_output *output;
|
||||||
struct drm_mode *drm_mode;
|
struct drm_mode *drm_mode, *next;
|
||||||
drmModeEncoder *encoder;
|
drmModeEncoder *encoder;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
unsigned handle, stride;
|
unsigned handle, stride;
|
||||||
@@ -467,11 +467,19 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
ec->connector_allocator |= (1 << output->connector_id);
|
ec->connector_allocator |= (1 << output->connector_id);
|
||||||
|
|
||||||
output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
|
output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
|
||||||
|
drmModeFreeEncoder(encoder);
|
||||||
|
|
||||||
for (i = 0; i < connector->count_modes; i++)
|
for (i = 0; i < connector->count_modes; i++) {
|
||||||
drm_output_add_mode(output, &connector->modes[i]);
|
ret = drm_output_add_mode(output, &connector->modes[i]);
|
||||||
if (connector->count_modes == 0)
|
if (ret)
|
||||||
drm_output_add_mode(output, &builtin_1024x768);
|
goto err_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
drm_mode = container_of(output->base.mode_list.next,
|
||||||
struct drm_mode, base.link);
|
struct drm_mode, base.link);
|
||||||
@@ -479,8 +487,6 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
drm_mode->base.flags =
|
drm_mode->base.flags =
|
||||||
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
|
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
|
||||||
|
|
||||||
drmModeFreeEncoder(encoder);
|
|
||||||
|
|
||||||
glGenRenderbuffers(2, output->rbo);
|
glGenRenderbuffers(2, output->rbo);
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, output->rbo[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;
|
output->base.destroy = drm_output_destroy;
|
||||||
|
|
||||||
return 0;
|
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
|
static int
|
||||||
|
|||||||
Reference in New Issue
Block a user