backend/native: Split up KMS shutdown in two phases

The first phase happens early, which discards pending page flips,
meaning the references held by those page flip closures are released.

The second phase happens late, after other units depending on the KMS
abstraction, have been cleaned up.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1822>
This commit is contained in:
Jonas Ådahl 2021-04-13 18:18:46 +02:00 committed by Marge Bot
parent 1af874fca6
commit 22417b8a94
9 changed files with 82 additions and 9 deletions

View File

@ -112,11 +112,13 @@ meta_backend_native_dispose (GObject *object)
native->udev_device_added_handler_id = 0;
}
g_clear_object (&native->kms);
g_clear_object (&native->udev);
if (native->kms)
meta_kms_prepare_shutdown (native->kms);
G_OBJECT_CLASS (meta_backend_native_parent_class)->dispose (object);
g_clear_object (&native->kms);
g_clear_object (&native->udev);
g_clear_pointer (&native->launcher, meta_launcher_free);
}

View File

@ -1011,15 +1011,24 @@ dispose_page_flip_data (gpointer key,
return TRUE;
}
static void
meta_kms_impl_device_atomic_prepare_shutdown (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDeviceAtomic *impl_device_atomic =
META_KMS_IMPL_DEVICE_ATOMIC (impl_device);
g_hash_table_foreach_remove (impl_device_atomic->page_flip_datas,
dispose_page_flip_data,
NULL);
}
static void
meta_kms_impl_device_atomic_finalize (GObject *object)
{
MetaKmsImplDeviceAtomic *impl_device_atomic =
META_KMS_IMPL_DEVICE_ATOMIC (object);
g_hash_table_foreach_remove (impl_device_atomic->page_flip_datas,
dispose_page_flip_data,
NULL);
g_assert (g_hash_table_size (impl_device_atomic->page_flip_datas) == 0);
g_hash_table_unref (impl_device_atomic->page_flip_datas);
@ -1039,10 +1048,7 @@ meta_kms_impl_device_atomic_initable_init (GInitable *initable,
static void
meta_kms_impl_device_atomic_init (MetaKmsImplDeviceAtomic *impl_device_atomic)
{
impl_device_atomic->page_flip_datas =
g_hash_table_new_full (NULL, NULL,
NULL,
(GDestroyNotify) meta_kms_page_flip_data_unref);
impl_device_atomic->page_flip_datas = g_hash_table_new (NULL, NULL);
}
static void
@ -1068,4 +1074,6 @@ meta_kms_impl_device_atomic_class_init (MetaKmsImplDeviceAtomicClass *klass)
meta_kms_impl_device_atomic_handle_page_flip_callback;
impl_device_class->discard_pending_page_flips =
meta_kms_impl_device_atomic_discard_pending_page_flips;
impl_device_class->prepare_shutdown =
meta_kms_impl_device_atomic_prepare_shutdown;
}

View File

@ -1488,6 +1488,18 @@ meta_kms_impl_device_simple_discard_pending_page_flips (MetaKmsImplDevice *impl_
g_source_destroy);
}
static void
meta_kms_impl_device_simple_prepare_shutdown (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
g_list_foreach (impl_device_simple->posted_page_flip_datas,
(GFunc) meta_kms_page_flip_data_discard_in_impl,
impl_device);
g_clear_list (&impl_device_simple->posted_page_flip_datas, NULL);
}
static void
meta_kms_impl_device_simple_finalize (GObject *object)
{
@ -1506,6 +1518,8 @@ meta_kms_impl_device_simple_finalize (GObject *object)
(GFunc) meta_kms_page_flip_data_discard_in_impl,
NULL);
g_assert (!impl_device_simple->posted_page_flip_datas);
g_clear_pointer (&impl_device_simple->mode_set_fallback_feedback_source,
g_source_destroy);
g_hash_table_destroy (impl_device_simple->cached_mode_sets);
@ -1583,4 +1597,6 @@ meta_kms_impl_device_simple_class_init (MetaKmsImplDeviceSimpleClass *klass)
meta_kms_impl_device_simple_handle_page_flip_callback;
impl_device_class->discard_pending_page_flips =
meta_kms_impl_device_simple_discard_pending_page_flips;
impl_device_class->prepare_shutdown =
meta_kms_impl_device_simple_prepare_shutdown;
}

View File

@ -836,6 +836,15 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
return TRUE;
}
void
meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
if (klass->prepare_shutdown)
klass->prepare_shutdown (impl_device);
}
static void
meta_kms_impl_device_init (MetaKmsImplDevice *impl_device)
{

View File

@ -68,6 +68,7 @@ struct _MetaKmsImplDeviceClass
void (* handle_page_flip_callback) (MetaKmsImplDevice *impl_device,
MetaKmsPageFlipData *page_flip_data);
void (* discard_pending_page_flips) (MetaKmsImplDevice *impl_device);
void (* prepare_shutdown) (MetaKmsImplDevice *impl_device);
};
MetaKmsDevice * meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device);
@ -143,4 +144,6 @@ int meta_kms_impl_device_close (MetaKmsImplDevice *impl_device);
gboolean meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
GError **error);
void meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device);
#endif /* META_KMS_IMPL_DEVICE_H */

View File

@ -103,6 +103,21 @@ meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl)
NULL);
}
void
meta_kms_impl_prepare_shutdown (MetaKmsImpl *impl)
{
MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
GList *l;
for (l = priv->impl_devices; l; l = l->next)
{
MetaKmsImplDevice *impl_device = l->data;
meta_kms_impl_device_discard_pending_page_flips (impl_device);
meta_kms_impl_device_prepare_shutdown (impl_device);
}
}
MetaKmsImpl *
meta_kms_impl_new (MetaKms *kms)
{

View File

@ -42,6 +42,8 @@ void meta_kms_impl_remove_impl_device (MetaKmsImpl *impl,
void meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl);
void meta_kms_impl_prepare_shutdown (MetaKmsImpl *impl);
MetaKmsImpl * meta_kms_impl_new (MetaKms *kms);
#endif /* META_KMS_IMPL_H */

View File

@ -662,6 +662,22 @@ meta_kms_new (MetaBackend *backend,
return kms;
}
static gpointer
prepare_shutdown_in_impl (MetaKmsImpl *impl,
gpointer user_data,
GError **error)
{
meta_kms_impl_prepare_shutdown (impl);
return GINT_TO_POINTER (TRUE);
}
void
meta_kms_prepare_shutdown (MetaKms *kms)
{
meta_kms_run_impl_task_sync (kms, prepare_shutdown_in_impl, NULL, NULL);
flush_callbacks (kms);
}
static void
meta_kms_finalize (GObject *object)
{

View File

@ -63,6 +63,8 @@ MetaKmsDevice * meta_kms_create_device (MetaKms *kms,
MetaKmsDeviceFlag flags,
GError **error);
void meta_kms_prepare_shutdown (MetaKms *kms);
MetaKms * meta_kms_new (MetaBackend *backend,
MetaKmsFlags flags,
GError **error);