diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 0fcc00c91..399560f1e 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -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); } diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c index d7c32a279..d1f2e7b82 100644 --- a/src/backends/native/meta-kms-impl-device-atomic.c +++ b/src/backends/native/meta-kms-impl-device-atomic.c @@ -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; } diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c index 5b7684efa..1519962b8 100644 --- a/src/backends/native/meta-kms-impl-device-simple.c +++ b/src/backends/native/meta-kms-impl-device-simple.c @@ -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; } diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index 4ed5479d6..9dc631b57 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -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) { diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h index 08d0011fb..6e8ec2378 100644 --- a/src/backends/native/meta-kms-impl-device.h +++ b/src/backends/native/meta-kms-impl-device.h @@ -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 */ diff --git a/src/backends/native/meta-kms-impl.c b/src/backends/native/meta-kms-impl.c index 87fe45492..036a0d783 100644 --- a/src/backends/native/meta-kms-impl.c +++ b/src/backends/native/meta-kms-impl.c @@ -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) { diff --git a/src/backends/native/meta-kms-impl.h b/src/backends/native/meta-kms-impl.h index 372f47721..723a21cd2 100644 --- a/src/backends/native/meta-kms-impl.h +++ b/src/backends/native/meta-kms-impl.h @@ -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 */ diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index 5135c4ca5..57bb88e5f 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -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) { diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h index 27b4e3537..79713cc40 100644 --- a/src/backends/native/meta-kms.h +++ b/src/backends/native/meta-kms.h @@ -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);