diff options
author | Jonas Ã…dahl <jadahl@gmail.com> | 2021-02-08 18:40:18 +0100 |
---|---|---|
committer | Robert Mader <robert.mader@posteo.de> | 2021-02-08 19:40:05 +0000 |
commit | c60cba4eeb4ba24b8fa6e736bb05e2a8e2a703e3 (patch) | |
tree | 1edb1a5ac612bcf23abc2f5b9c30ff3ee994c21a | |
parent | b838ba8166bf9af170181a59aafa1c5bbc98b915 (diff) | |
download | mutter-c60cba4eeb4ba24b8fa6e736bb05e2a8e2a703e3.tar.gz |
tests: Add test for destroyed frame clock free timeline actor
This would without 'clutter/timeline: Clear stage view listener when
actor destroyed' result in backtraces such as
Program terminated with signal SIGSEGV, Segmentation fault.
#0 on_stage_stage_views_changed ()
#1 g_closure_invoke ()
#2 signal_emit_unlocked_R ()
#3 g_signal_emit_valist ()
#4 g_signal_emit ()
#5 update_stage_views ()
#6 clutter_actor_update_stage_views ()
#7 clutter_stage_update_actor_stage_views ()
#8 handle_frame_clock_frame ()
#9 clutter_frame_clock_dispatch ()
#10 frame_clock_source_dispatch ()
#11 g_main_dispatch ()
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1719>
-rw-r--r-- | src/tests/stage-view-tests.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/tests/stage-view-tests.c b/src/tests/stage-view-tests.c index 9604a4ab5..101fbdcda 100644 --- a/src/tests/stage-view-tests.c +++ b/src/tests/stage-view-tests.c @@ -1078,6 +1078,81 @@ meta_test_actor_stage_views_and_frame_clocks_freed (void) } static void +ensure_view_count (int n_views) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + MonitorTestCaseSetup test_case_setup; + MetaMonitorTestSetup *test_setup; + + test_case_setup = initial_test_case_setup; + test_case_setup.n_outputs = n_views; + test_case_setup.n_crtcs = n_views; + test_setup = create_monitor_test_setup (&test_case_setup, + MONITOR_TEST_FLAG_NO_STORED); + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); +} + +static void +meta_test_timeline_actor_destroyed (void) +{ + MetaBackend *backend = meta_get_backend (); + ClutterActor *stage; + GList *stage_views; + ClutterActor *persistent_actor; + ClutterActor *actor; + ClutterTimeline *timeline; + gboolean did_stage_views_changed = FALSE; + + ensure_view_count (0); + + stage = meta_backend_get_stage (backend); + clutter_actor_show (stage); + + persistent_actor = clutter_actor_new (); + clutter_actor_add_child (stage, persistent_actor); + + stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage)); + g_assert_null (stage_views); + stage_views = clutter_actor_peek_stage_views (stage); + g_assert_null (stage_views); + g_assert_null (clutter_actor_pick_frame_clock (stage, NULL)); + + actor = clutter_actor_new (); + clutter_actor_add_child (stage, actor); + g_assert_null (clutter_actor_pick_frame_clock (actor, NULL)); + + timeline = clutter_timeline_new_for_actor (actor, 100); + clutter_timeline_start (timeline); + + g_signal_connect (stage, "stage-views-changed", + G_CALLBACK (on_stage_views_changed), + &did_stage_views_changed); + + clutter_actor_destroy (actor); + g_object_unref (timeline); + + ensure_view_count (1); + + stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage)); + g_assert_cmpint (g_list_length (stage_views), ==, 1); + + g_assert_false (did_stage_views_changed); + clutter_actor_queue_redraw (persistent_actor); + clutter_stage_schedule_update (CLUTTER_STAGE (stage)); + wait_for_paint (stage); + g_assert_true (did_stage_views_changed); + + g_signal_handlers_disconnect_by_func (stage, on_stage_views_changed, + &did_stage_views_changed); + + clutter_actor_destroy (persistent_actor); +} + +static void init_tests (int argc, char **argv) { meta_monitor_manager_test_init_test_setup (create_stage_view_test_setup); @@ -1104,6 +1179,8 @@ init_tests (int argc, char **argv) meta_test_actor_stage_views_parent_views_changed); g_test_add_func ("/stage-views/actor-stage-views-and-frame-clocks-freed", meta_test_actor_stage_views_and_frame_clocks_freed); + g_test_add_func ("/stage-views/timeline/actor-destroyed", + meta_test_timeline_actor_destroyed); } int |