output:fix seg fault in transmitter when weston terminates 84/22884/1
authorVeeresh Kadasani <external.vkadasani@jp.adit-jv.com>
Wed, 6 Nov 2019 06:46:39 +0000 (15:46 +0900)
committerVeeresh Kadasani <external.vkadasani@jp.adit-jv.com>
Fri, 8 Nov 2019 01:25:16 +0000 (01:25 +0000)
Bug-AGL: SPEC-2939

If we stop weston with kill command weston doesn't terminate
properly and receives segmentation fault beacause of double free
output->link which happened because of wrongly calling
weston_output_destroy inside transmitter_destroy function.
Also initialize transmitter_output_disable to base disable pointer.

Change-Id: I2adda6eba7d260398d3e871fc21bf8f04d59cf0b
Signed-off-by: Veeresh Kadasani <external.vkadasani@jp.adit-jv.com>
(cherry picked from commit 8409a6d28957c6edd9caae8143ee54877e0e1256)

waltham-transmitter/transmitter-plugin/output.c

index dc7d5d8..0676655 100644 (file)
@@ -117,6 +117,14 @@ free_mode_list(struct wl_list *mode_list)
        }
 }
 
+static int
+transmitter_output_disable(struct weston_output *base)
+{
+       struct weston_transmitter_output *output = wl_container_of(base, output, base);
+       wl_event_source_remove(output->finish_frame_timer);
+       return 0;
+}
+
 void
 transmitter_output_destroy(struct weston_transmitter_output *output)
 {
@@ -126,8 +134,8 @@ transmitter_output_destroy(struct weston_transmitter_output *output)
        free_mode_list(&output->base.mode_list);
        weston_head_release(head);
        free(head);
-
-       weston_output_destroy(&output->base);
+       transmitter_output_disable(&output->base);
+       weston_output_release(&output->base);
        free(output);
 }
 
@@ -342,6 +350,7 @@ transmitter_remote_create_output(struct weston_transmitter_remote *remote,
        output->base.start_repaint_loop = transmitter_start_repaint_loop;
        output->base.repaint = transmitter_output_repaint;
        output->base.destroy = transmitter_output_destroy_;
+       output->base.disable = transmitter_output_disable;
        output->base.assign_planes = NULL;
        output->base.set_dpms = NULL;
        output->base.switch_mode = NULL;