seat/native: Explicitly destroy MetaSeatImpl

We can't post tasks to the input thread when cleaning up the
MetaSeatImpl, as that will make the GTask complain about adding
references to a to be purged object. Avoid this by adding an explicit
meta_seat_impl_destroy() function that handles the destruction of the
MetaSeatImpl properly.

This also does more of the cleanup in the input thread, as that is where
it was managed. Will likely not make a difference as before this
happened after tearing down the thread, but lets tear down things in the
thread they were managed for good measure.

This fixes the last log spew I see right now when terminating mutter.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1670>
This commit is contained in:
Jonas Ådahl 2021-01-14 16:07:40 +01:00
parent 904116fe4d
commit 05765daabf
3 changed files with 44 additions and 37 deletions

View File

@ -2753,7 +2753,8 @@ meta_seat_impl_get_property (GObject *object,
static gboolean
destroy_in_impl (GTask *task)
{
MetaSeatImpl *seat_impl = g_task_get_task_data (task);
MetaSeatImpl *seat_impl = g_task_get_source_object (task);
gboolean numlock_active;
g_slist_foreach (seat_impl->devices,
(GFunc) meta_input_device_native_detach_libinput_in_impl,
@ -2762,41 +2763,10 @@ destroy_in_impl (GTask *task)
seat_impl->devices = NULL;
g_clear_pointer (&seat_impl->libinput, libinput_unref);
g_main_loop_quit (seat_impl->input_loop);
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
static void
meta_seat_impl_finalize (GObject *object)
{
MetaSeatImpl *seat_impl = META_SEAT_IMPL (object);
gboolean numlock_active;
if (seat_impl->libinput)
{
GTask *task;
task = g_task_new (seat_impl, NULL, NULL, NULL);
g_task_set_task_data (task, seat_impl, NULL);
meta_seat_impl_run_input_task (seat_impl, task,
(GSourceFunc) destroy_in_impl);
g_object_unref (task);
g_thread_join (seat_impl->input_thread);
g_assert (!seat_impl->libinput);
}
g_clear_pointer (&seat_impl->tools, g_hash_table_unref);
if (seat_impl->touch_states)
g_hash_table_destroy (seat_impl->touch_states);
g_object_unref (seat_impl->udev_client);
meta_event_source_free (seat_impl->event_source);
g_clear_pointer (&seat_impl->touch_states, g_hash_table_destroy);
g_clear_object (&seat_impl->udev_client);
g_clear_pointer (&seat_impl->event_source, meta_event_source_free);
numlock_active =
xkb_state_mod_name_is_active (seat_impl->xkb, XKB_MOD_NAME_NUM,
@ -2805,10 +2775,45 @@ meta_seat_impl_finalize (GObject *object)
meta_input_settings_maybe_save_numlock_state (seat_impl->input_settings,
numlock_active);
xkb_state_unref (seat_impl->xkb);
g_clear_pointer (&seat_impl->xkb, xkb_state_unref);
meta_seat_impl_clear_repeat_source (seat_impl);
g_main_loop_quit (seat_impl->input_loop);
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
void
meta_seat_impl_destroy (MetaSeatImpl *seat_impl)
{
if (seat_impl->libinput)
{
GTask *task;
task = g_task_new (seat_impl, NULL, NULL, NULL);
meta_seat_impl_run_input_task (seat_impl, task,
(GSourceFunc) destroy_in_impl);
g_object_unref (task);
g_thread_join (seat_impl->input_thread);
g_assert (!seat_impl->libinput);
}
g_object_unref (seat_impl);
}
static void
meta_seat_impl_finalize (GObject *object)
{
MetaSeatImpl *seat_impl = META_SEAT_IMPL (object);
g_assert (!seat_impl->libinput);
g_assert (!seat_impl->tools);
g_assert (!seat_impl->udev_client);
g_assert (!seat_impl->event_source);
g_free (seat_impl->seat_id);
g_rw_lock_clear (&seat_impl->state_lock);

View File

@ -129,6 +129,8 @@ G_DECLARE_FINAL_TYPE (MetaSeatImpl, meta_seat_impl,
MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat_native,
const char *seat_id);
void meta_seat_impl_destroy (MetaSeatImpl *seat_impl);
void meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl,
GTask *task,
GSourceFunc dispatch_func);

View File

@ -225,7 +225,7 @@ meta_seat_native_finalize (GObject *object)
xkb_keymap_unref (seat->xkb_keymap);
g_clear_object (&seat->core_pointer);
g_clear_object (&seat->core_keyboard);
g_clear_object (&seat->impl);
g_clear_pointer (&seat->impl, meta_seat_impl_destroy);
for (iter = seat->devices; iter; iter = g_list_next (iter))
{