From a6baa77eab89294fb96976204618e4a1f6bea5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 22 Nov 2020 17:56:04 +0100 Subject: [PATCH] kms: Split out impl/non-impl separation into MetaThread(Impl) It currently does exactly what MetaKms and MetaKmsImpl did regarding the context separation, which is to isolate what may eventually run on a KMS thread into a separate unit. It works somewhat like a "user thread", i.e. not a real thread, but will eventually learn how to spawn a "kernel thread", but provide the same API from the outside. Part-of: --- src/backends/native/meta-kms-device.c | 25 +- src/backends/native/meta-kms-impl-device.c | 12 +- src/backends/native/meta-kms-impl.c | 75 +--- src/backends/native/meta-kms-impl.h | 3 +- src/backends/native/meta-kms-page-flip.c | 18 +- src/backends/native/meta-kms-private.h | 28 +- src/backends/native/meta-kms.c | 297 ++++---------- src/backends/native/meta-kms.h | 3 +- src/backends/native/meta-thread-impl.c | 142 +++++++ src/backends/native/meta-thread-impl.h | 40 ++ src/backends/native/meta-thread-private.h | 31 ++ src/backends/native/meta-thread.c | 428 +++++++++++++++++++++ src/backends/native/meta-thread.h | 81 ++++ src/meson.build | 6 + 14 files changed, 843 insertions(+), 346 deletions(-) create mode 100644 src/backends/native/meta-thread-impl.c create mode 100644 src/backends/native/meta-thread-impl.h create mode 100644 src/backends/native/meta-thread-private.h create mode 100644 src/backends/native/meta-thread.c create mode 100644 src/backends/native/meta-thread.h diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c index d752ef825..b59c95dba 100644 --- a/src/backends/native/meta-kms-device.c +++ b/src/backends/native/meta-kms-device.c @@ -232,9 +232,9 @@ meta_kms_device_get_fallback_modes (MetaKmsDevice *device) } static gpointer -disable_device_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +disable_device_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) { MetaKmsImplDevice *impl_device = user_data; @@ -289,9 +289,9 @@ typedef struct } PostUpdateData; static gpointer -process_update_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +process_update_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) { PostUpdateData *data = user_data; MetaKmsUpdate *update = data->update; @@ -484,10 +484,11 @@ meta_create_kms_impl_device (MetaKmsDevice *device, } static gpointer -create_impl_device_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +create_impl_device_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) { + MetaKmsImpl *impl = META_KMS_IMPL (thread_impl); CreateImplDeviceData *data = user_data; MetaKmsImplDevice *impl_device; @@ -561,9 +562,9 @@ meta_kms_device_new (MetaKms *kms, } static gpointer -free_impl_device_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +free_impl_device_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) { MetaKmsImplDevice *impl_device = user_data; diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index d56636d55..afbf5b4c5 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -248,9 +248,9 @@ meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device, } static gpointer -kms_event_dispatch_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +kms_event_dispatch_in_impl (MetaThreadImpl *impl, + gpointer user_data, + GError **error) { MetaKmsImplDevice *impl_device = user_data; gboolean ret; @@ -992,12 +992,12 @@ meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device) } static void -emit_resources_changed_callback (MetaKms *kms, - gpointer user_data) +emit_resources_changed_callback (MetaThread *thread, + gpointer user_data) { MetaKmsResourceChanges changes = GPOINTER_TO_UINT (user_data); - meta_kms_emit_resources_changed (kms, changes); + meta_kms_emit_resources_changed (META_KMS (thread), changes); } static void diff --git a/src/backends/native/meta-kms-impl.c b/src/backends/native/meta-kms-impl.c index 5ccd80fc8..780019c72 100644 --- a/src/backends/native/meta-kms-impl.c +++ b/src/backends/native/meta-kms-impl.c @@ -26,13 +26,6 @@ #include "backends/native/meta-kms-device-private.h" #include "backends/native/meta-kms-update-private.h" -enum -{ - PROP_0, - - PROP_KMS, -}; - struct _MetaKmsImpl { GObject parent; @@ -40,19 +33,17 @@ struct _MetaKmsImpl typedef struct _MetaKmsImplPrivate { - MetaKms *kms; - GList *impl_devices; } MetaKmsImplPrivate; -G_DEFINE_TYPE_WITH_PRIVATE (MetaKmsImpl, meta_kms_impl, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_PRIVATE (MetaKmsImpl, meta_kms_impl, META_TYPE_THREAD_IMPL) MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl) { - MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); + MetaThreadImpl *thread_impl = META_THREAD_IMPL (impl); - return priv->kms; + return META_KMS (meta_thread_impl_get_thread (thread_impl)); } void @@ -61,7 +52,7 @@ meta_kms_impl_add_impl_device (MetaKmsImpl *impl, { MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); - meta_assert_in_kms_impl (priv->kms); + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl)); priv->impl_devices = g_list_append (priv->impl_devices, impl_device); } @@ -72,7 +63,7 @@ meta_kms_impl_remove_impl_device (MetaKmsImpl *impl, { MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); - meta_assert_in_kms_impl (priv->kms); + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl)); priv->impl_devices = g_list_remove (priv->impl_devices, impl_device); } @@ -120,46 +111,6 @@ meta_kms_impl_new (MetaKms *kms) NULL); } -static void -meta_kms_impl_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - MetaKmsImpl *impl = META_KMS_IMPL (object); - MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); - - switch (prop_id) - { - case PROP_KMS: - priv->kms = g_value_get_object (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -meta_kms_impl_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MetaKmsImpl *impl = META_KMS_IMPL (object); - MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); - - switch (prop_id) - { - case PROP_KMS: - g_value_set_object (value, priv->kms); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - static void meta_kms_impl_init (MetaKmsImpl *kms_impl) { @@ -168,20 +119,4 @@ meta_kms_impl_init (MetaKmsImpl *kms_impl) static void meta_kms_impl_class_init (MetaKmsImplClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - object_class->set_property = meta_kms_impl_set_property; - object_class->get_property = meta_kms_impl_get_property; - - pspec = g_param_spec_object ("kms", - "kms", - "MetaKms", - META_TYPE_KMS, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_property (object_class, - PROP_KMS, - pspec); } diff --git a/src/backends/native/meta-kms-impl.h b/src/backends/native/meta-kms-impl.h index c85320c9b..d2de35d30 100644 --- a/src/backends/native/meta-kms-impl.h +++ b/src/backends/native/meta-kms-impl.h @@ -24,10 +24,11 @@ #include "backends/native/meta-kms-impl-device.h" #include "backends/native/meta-kms-page-flip-private.h" #include "backends/native/meta-kms.h" +#include "backends/native/meta-thread-impl.h" #define META_TYPE_KMS_IMPL (meta_kms_impl_get_type ()) G_DECLARE_FINAL_TYPE (MetaKmsImpl, meta_kms_impl, - META, KMS_IMPL, GObject) + META, KMS_IMPL, MetaThreadImpl) MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl); diff --git a/src/backends/native/meta-kms-page-flip.c b/src/backends/native/meta-kms-page-flip.c index c1c29905c..c3faf8271 100644 --- a/src/backends/native/meta-kms-page-flip.c +++ b/src/backends/native/meta-kms-page-flip.c @@ -142,13 +142,13 @@ meta_kms_page_flip_data_get_crtc (MetaKmsPageFlipData *page_flip_data) } static void -meta_kms_page_flip_data_flipped (MetaKms *kms, - gpointer user_data) +meta_kms_page_flip_data_flipped (MetaThread *thread, + gpointer user_data) { MetaKmsPageFlipData *page_flip_data = user_data; GList *l; - meta_assert_not_in_kms_impl (kms); + meta_assert_not_in_kms_impl (META_KMS (thread)); for (l = page_flip_data->closures; l; l = l->next) { @@ -219,13 +219,13 @@ meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data) } static void -meta_kms_page_flip_data_mode_set_fallback (MetaKms *kms, - gpointer user_data) +meta_kms_page_flip_data_mode_set_fallback (MetaThread *thread, + gpointer user_data) { MetaKmsPageFlipData *page_flip_data = user_data; GList *l; - meta_assert_not_in_kms_impl (kms); + meta_assert_not_in_kms_impl (META_KMS (thread)); for (l = page_flip_data->closures; l; l = l->next) { @@ -250,13 +250,13 @@ meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_fli } static void -meta_kms_page_flip_data_discard (MetaKms *kms, - gpointer user_data) +meta_kms_page_flip_data_discard (MetaThread *thread, + gpointer user_data) { MetaKmsPageFlipData *page_flip_data = user_data; GList *l; - meta_assert_not_in_kms_impl (kms); + meta_assert_not_in_kms_impl (META_KMS (thread)); for (l = page_flip_data->closures; l; l = l->next) { diff --git a/src/backends/native/meta-kms-private.h b/src/backends/native/meta-kms-private.h index 16ecf2470..3ea2c867f 100644 --- a/src/backends/native/meta-kms-private.h +++ b/src/backends/native/meta-kms-private.h @@ -30,32 +30,28 @@ typedef void (* MetaKmsCallback) (MetaKms *kms, gpointer user_data); -typedef gpointer (* MetaKmsImplTaskFunc) (MetaKmsImpl *impl, - gpointer user_data, - GError **error); - -void meta_kms_queue_callback (MetaKms *kms, - MetaKmsCallback callback, - gpointer user_data, - GDestroyNotify user_data_destroy); +void meta_kms_queue_callback (MetaKms *kms, + MetaThreadCallback callback, + gpointer user_data, + GDestroyNotify user_data_destroy); void meta_kms_queue_result_callback (MetaKms *kms, MetaKmsResultListener *listener); -gpointer meta_kms_run_impl_task_sync (MetaKms *kms, - MetaKmsImplTaskFunc func, - gpointer user_data, - GError **error); +gpointer meta_kms_run_impl_task_sync (MetaKms *kms, + MetaThreadTaskFunc func, + gpointer user_data, + GError **error); GSource * meta_kms_add_source_in_impl (MetaKms *kms, GSourceFunc func, gpointer user_data, GDestroyNotify user_data_destroy); -GSource * meta_kms_register_fd_in_impl (MetaKms *kms, - int fd, - MetaKmsImplTaskFunc dispatch, - gpointer user_data); +GSource * meta_kms_register_fd_in_impl (MetaKms *kms, + int fd, + MetaThreadTaskFunc dispatch, + gpointer user_data); META_EXPORT_TEST MetaKmsResourceChanges meta_kms_update_states_sync (MetaKms *kms, diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index d3a840b31..f1dc310ac 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -26,6 +26,7 @@ #include "backends/native/meta-kms-device-private.h" #include "backends/native/meta-kms-impl.h" #include "backends/native/meta-kms-update-private.h" +#include "backends/native/meta-thread-private.h" #include "backends/native/meta-udev.h" #include "cogl/cogl.h" @@ -132,38 +133,12 @@ enum static int signals[N_SIGNALS]; -typedef struct _MetaKmsCallbackData -{ - MetaKmsCallback callback; - gpointer user_data; - GDestroyNotify user_data_destroy; -} MetaKmsCallbackData; - -typedef struct _MetaKmsSimpleImplSource -{ - GSource source; - MetaKms *kms; -} MetaKmsSimpleImplSource; - -typedef struct _MetaKmsFdImplSource -{ - GSource source; - - gpointer fd_tag; - MetaKms *kms; - - MetaKmsImplTaskFunc dispatch; - gpointer user_data; -} MetaKmsFdImplSource; - struct _MetaKms { - GObject parent; + MetaThread parent; MetaKmsFlags flags; - MetaBackend *backend; - gulong hotplug_handler_id; gulong removed_handler_id; @@ -179,11 +154,11 @@ struct _MetaKms guint callback_source_id; }; -G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT) +G_DEFINE_TYPE (MetaKms, meta_kms, META_TYPE_THREAD) static void -invoke_result_listener (MetaKms *kms, - gpointer user_data) +invoke_result_listener (MetaThread *thread, + gpointer user_data) { MetaKmsResultListener *listener = user_data; @@ -201,10 +176,12 @@ meta_kms_queue_result_callback (MetaKms *kms, } static gpointer -meta_kms_discard_pending_page_flips_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +meta_kms_discard_pending_page_flips_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) { + MetaKmsImpl *impl = META_KMS_IMPL (thread_impl); + meta_kms_impl_discard_pending_page_flips (impl); return GINT_TO_POINTER (TRUE); } @@ -219,10 +196,12 @@ meta_kms_discard_pending_page_flips (MetaKms *kms) } static gpointer -meta_kms_notify_modes_set_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +meta_kms_notify_modes_set_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) { + MetaKmsImpl *impl = META_KMS_IMPL (thread_impl); + meta_kms_impl_notify_modes_set (impl); return GINT_TO_POINTER (TRUE); } @@ -230,212 +209,73 @@ meta_kms_notify_modes_set_in_impl (MetaKmsImpl *impl, void meta_kms_notify_modes_set (MetaKms *kms) { - meta_kms_run_impl_task_sync (kms, - meta_kms_notify_modes_set_in_impl, - NULL, - NULL); -} + MetaThread *thread = META_THREAD (kms); -static void -meta_kms_callback_data_free (MetaKmsCallbackData *callback_data) -{ - if (callback_data->user_data_destroy) - callback_data->user_data_destroy (callback_data->user_data); - g_free (callback_data); -} - -static int -flush_callbacks (MetaKms *kms) -{ - GList *l; - int callback_count = 0; - - meta_assert_not_in_kms_impl (kms); - - g_clear_handle_id (&kms->callback_source_id, g_source_remove); - - for (l = kms->pending_callbacks; l; l = l->next) - { - MetaKmsCallbackData *callback_data = l->data; - - callback_data->callback (kms, callback_data->user_data); - meta_kms_callback_data_free (callback_data); - callback_count++; - } - - g_list_free (kms->pending_callbacks); - kms->pending_callbacks = NULL; - - return callback_count; -} - -static gboolean -callback_idle (gpointer user_data) -{ - MetaKms *kms = user_data; - - flush_callbacks (kms); - - kms->callback_source_id = 0; - return G_SOURCE_REMOVE; + meta_thread_run_impl_task_sync (thread, + meta_kms_notify_modes_set_in_impl, + NULL, + NULL); } void -meta_kms_queue_callback (MetaKms *kms, - MetaKmsCallback callback, - gpointer user_data, - GDestroyNotify user_data_destroy) +meta_kms_queue_callback (MetaKms *kms, + MetaThreadCallback callback, + gpointer user_data, + GDestroyNotify user_data_destroy) { - MetaKmsCallbackData *callback_data; + MetaThread *thread = META_THREAD (kms); - callback_data = g_new0 (MetaKmsCallbackData, 1); - *callback_data = (MetaKmsCallbackData) { - .callback = callback, - .user_data = user_data, - .user_data_destroy = user_data_destroy, - }; - kms->pending_callbacks = g_list_append (kms->pending_callbacks, - callback_data); - if (!kms->callback_source_id) - kms->callback_source_id = g_idle_add (callback_idle, kms); + meta_thread_queue_callback (thread, callback, user_data, user_data_destroy); } gpointer -meta_kms_run_impl_task_sync (MetaKms *kms, - MetaKmsImplTaskFunc func, - gpointer user_data, - GError **error) +meta_kms_run_impl_task_sync (MetaKms *kms, + MetaThreadTaskFunc func, + gpointer user_data, + GError **error) { - gpointer ret; + MetaThread *thread = META_THREAD (kms); - kms->in_impl_task = TRUE; - kms->waiting_for_impl_task = TRUE; - ret = func (kms->impl, user_data, error); - kms->waiting_for_impl_task = FALSE; - kms->in_impl_task = FALSE; - - return ret; + return meta_thread_run_impl_task_sync (thread, func, user_data, error); } -static gboolean -simple_impl_source_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - MetaKmsSimpleImplSource *simple_impl_source = - (MetaKmsSimpleImplSource *) source; - MetaKms *kms = simple_impl_source->kms; - gboolean ret; - - kms->in_impl_task = TRUE; - ret = callback (user_data); - kms->in_impl_task = FALSE; - - return ret; -} - -static GSourceFuncs simple_impl_source_funcs = { - .dispatch = simple_impl_source_dispatch, -}; - GSource * meta_kms_add_source_in_impl (MetaKms *kms, GSourceFunc func, gpointer user_data, GDestroyNotify user_data_destroy) { - GSource *source; - MetaKmsSimpleImplSource *simple_impl_source; + MetaThread *thread = META_THREAD (kms); - meta_assert_in_kms_impl (kms); - - source = g_source_new (&simple_impl_source_funcs, - sizeof (MetaKmsSimpleImplSource)); - g_source_set_name (source, "[mutter] KMS simple impl"); - simple_impl_source = (MetaKmsSimpleImplSource *) source; - simple_impl_source->kms = kms; - - g_source_set_callback (source, func, user_data, user_data_destroy); - g_source_set_ready_time (source, 0); - g_source_attach (source, g_main_context_get_thread_default ()); - - return source; + return meta_thread_add_source_in_impl (thread, func, + user_data, user_data_destroy); } -static gboolean -meta_kms_fd_impl_source_check (GSource *source) -{ - MetaKmsFdImplSource *fd_impl_source = (MetaKmsFdImplSource *) source; - - return g_source_query_unix_fd (source, fd_impl_source->fd_tag) & G_IO_IN; -} - -static gboolean -meta_kms_fd_impl_source_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - MetaKmsFdImplSource *fd_impl_source = (MetaKmsFdImplSource *) source; - MetaKms *kms = fd_impl_source->kms; - gpointer ret; - GError *error = NULL; - - kms->in_impl_task = TRUE; - ret = fd_impl_source->dispatch (kms->impl, - fd_impl_source->user_data, - &error); - kms->in_impl_task = FALSE; - - if (!GPOINTER_TO_INT (ret)) - { - g_warning ("Failed to dispatch fd source: %s", error->message); - g_error_free (error); - } - - return G_SOURCE_CONTINUE; -} - -static GSourceFuncs fd_impl_source_funcs = { - NULL, - meta_kms_fd_impl_source_check, - meta_kms_fd_impl_source_dispatch -}; - GSource * -meta_kms_register_fd_in_impl (MetaKms *kms, - int fd, - MetaKmsImplTaskFunc dispatch, - gpointer user_data) +meta_kms_register_fd_in_impl (MetaKms *kms, + int fd, + MetaThreadTaskFunc dispatch, + gpointer user_data) { - GSource *source; - MetaKmsFdImplSource *fd_impl_source; + MetaThread *thread = META_THREAD (kms); - meta_assert_in_kms_impl (kms); - - source = g_source_new (&fd_impl_source_funcs, sizeof (MetaKmsFdImplSource)); - g_source_set_name (source, "[mutter] KMS fd impl"); - fd_impl_source = (MetaKmsFdImplSource *) source; - fd_impl_source->dispatch = dispatch; - fd_impl_source->user_data = user_data; - fd_impl_source->kms = kms; - fd_impl_source->fd_tag = g_source_add_unix_fd (source, fd, - G_IO_IN | G_IO_ERR); - - g_source_attach (source, g_main_context_get_thread_default ()); - - return source; + return meta_thread_register_fd_in_impl (thread, fd, dispatch, user_data); } gboolean meta_kms_in_impl_task (MetaKms *kms) { - return kms->in_impl_task; + MetaThread *thread = META_THREAD (kms); + + return meta_thread_is_in_impl_task (thread); } gboolean meta_kms_is_waiting_for_impl_task (MetaKms *kms) { - return kms->waiting_for_impl_task; + MetaThread *thread = META_THREAD (kms); + + return meta_thread_is_waiting_for_impl_task (thread); } typedef struct _UpdateStatesData @@ -488,11 +328,12 @@ meta_kms_update_states_in_impl (MetaKms *kms, } static gpointer -update_states_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +update_states_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) { UpdateStatesData *data = user_data; + MetaKmsImpl *impl = META_KMS_IMPL (thread_impl); MetaKms *kms = meta_kms_impl_get_kms (impl); return GUINT_TO_POINTER (meta_kms_update_states_in_impl (kms, data)); @@ -557,7 +398,7 @@ on_udev_device_removed (MetaUdev *udev, MetaBackend * meta_kms_get_backend (MetaKms *kms) { - return kms->backend; + return meta_thread_get_backend (META_THREAD (kms)); } GList * @@ -587,10 +428,12 @@ meta_kms_create_device (MetaKms *kms, } static gpointer -prepare_shutdown_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +prepare_shutdown_in_impl (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error) { + MetaKmsImpl *impl = META_KMS_IMPL (thread_impl); + meta_kms_impl_prepare_shutdown (impl); return GINT_TO_POINTER (TRUE); } @@ -600,7 +443,7 @@ on_prepare_shutdown (MetaBackend *backend, MetaKms *kms) { meta_kms_run_impl_task_sync (kms, prepare_shutdown_in_impl, NULL, NULL); - flush_callbacks (kms); + meta_thread_flush_callbacks (META_THREAD (kms)); } MetaKms * @@ -612,15 +455,10 @@ meta_kms_new (MetaBackend *backend, MetaUdev *udev = meta_backend_native_get_udev (backend_native); MetaKms *kms; - kms = g_object_new (META_TYPE_KMS, NULL); + kms = g_object_new (META_TYPE_KMS, + "backend", backend, + NULL); kms->flags = flags; - kms->backend = backend; - kms->impl = meta_kms_impl_new (kms); - if (!kms->impl) - { - g_object_unref (kms); - return NULL; - } if (!(flags & META_KMS_FLAG_NO_MODE_SETTING)) { @@ -643,15 +481,9 @@ static void meta_kms_finalize (GObject *object) { MetaKms *kms = META_KMS (object); - MetaBackendNative *backend_native = META_BACKEND_NATIVE (kms->backend); + MetaBackend *backend = meta_thread_get_backend (META_THREAD (kms)); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaUdev *udev = meta_backend_native_get_udev (backend_native); - GList *l; - - for (l = kms->pending_callbacks; l; l = l->next) - meta_kms_callback_data_free (l->data); - g_list_free (kms->pending_callbacks); - - g_clear_handle_id (&kms->callback_source_id, g_source_remove); g_list_free_full (kms->devices, g_object_unref); @@ -675,6 +507,7 @@ static void meta_kms_class_init (MetaKmsClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaThreadClass *thread_class = META_THREAD_CLASS (klass); object_class->finalize = meta_kms_finalize; object_class->constructed = meta_kms_constructed; @@ -687,6 +520,8 @@ meta_kms_class_init (MetaKmsClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 1, META_TYPE_KMS_RESOURCE_CHANGES); + + meta_thread_class_register_impl_type (thread_class, META_TYPE_KMS_IMPL); } void diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h index fe4fef1a0..a0e8b2bb8 100644 --- a/src/backends/native/meta-kms.h +++ b/src/backends/native/meta-kms.h @@ -24,6 +24,7 @@ #include "backends/meta-backend-private.h" #include "backends/native/meta-kms-types.h" +#include "backends/native/meta-thread.h" typedef enum _MetaKmsFlags { @@ -32,7 +33,7 @@ typedef enum _MetaKmsFlags } MetaKmsFlags; #define META_TYPE_KMS (meta_kms_get_type ()) -G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject) +G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, MetaThread) void meta_kms_discard_pending_page_flips (MetaKms *kms); diff --git a/src/backends/native/meta-thread-impl.c b/src/backends/native/meta-thread-impl.c new file mode 100644 index 000000000..e8e9b85c5 --- /dev/null +++ b/src/backends/native/meta-thread-impl.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2018-2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-thread-impl.h" + +#include + +#include "backends/native/meta-thread.h" + +enum +{ + PROP_0, + + PROP_THREAD, + + N_PROPS +}; + +static GParamSpec *obj_props[N_PROPS]; + +typedef struct _MetaThreadImplPrivate +{ + MetaThread *thread; + GMainContext *thread_context; +} MetaThreadImplPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaThreadImpl, meta_thread_impl, G_TYPE_OBJECT) + +static void +meta_thread_impl_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaThreadImpl *thread_impl = META_THREAD_IMPL (object); + MetaThreadImplPrivate *priv = + meta_thread_impl_get_instance_private (thread_impl); + + switch (prop_id) + { + case PROP_THREAD: + g_value_set_object (value, priv->thread); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_thread_impl_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaThreadImpl *thread_impl = META_THREAD_IMPL (object); + MetaThreadImplPrivate *priv = + meta_thread_impl_get_instance_private (thread_impl); + + switch (prop_id) + { + case PROP_THREAD: + priv->thread = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_thread_impl_constructed (GObject *object) +{ + MetaThreadImpl *thread_impl = META_THREAD_IMPL (object); + MetaThreadImplPrivate *priv = + meta_thread_impl_get_instance_private (thread_impl); + + G_OBJECT_CLASS (meta_thread_impl_parent_class)->constructed (object); + + priv->thread_context = g_main_context_get_thread_default (); +} + +static void +meta_thread_impl_class_init (MetaThreadImplClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = meta_thread_impl_get_property; + object_class->set_property = meta_thread_impl_set_property; + object_class->constructed = meta_thread_impl_constructed; + + obj_props[PROP_THREAD] = + g_param_spec_object ("thread", + "thread", + "MetaThread", + META_TYPE_THREAD, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPS, obj_props); +} + +static void +meta_thread_impl_init (MetaThreadImpl *thread_impl) +{ +} + +MetaThread * +meta_thread_impl_get_thread (MetaThreadImpl *thread_impl) +{ + MetaThreadImplPrivate *priv = + meta_thread_impl_get_instance_private (thread_impl); + + return priv->thread; +} + +GMainContext * +meta_thread_impl_get_main_context (MetaThreadImpl *thread_impl) +{ + MetaThreadImplPrivate *priv = + meta_thread_impl_get_instance_private (thread_impl); + + return priv->thread_context; +} diff --git a/src/backends/native/meta-thread-impl.h b/src/backends/native/meta-thread-impl.h new file mode 100644 index 000000000..776755889 --- /dev/null +++ b/src/backends/native/meta-thread-impl.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2018-2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_THREAD_IMPL_H +#define META_THREAD_IMPL_H + +#include + +typedef struct _MetaThread MetaThread; + +#define META_TYPE_THREAD_IMPL (meta_thread_impl_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaThreadImpl, meta_thread_impl, + META, THREAD_IMPL, GObject) + +struct _MetaThreadImplClass +{ + GObjectClass parent_class; +}; + +MetaThread * meta_thread_impl_get_thread (MetaThreadImpl *thread_impl); + +GMainContext * meta_thread_impl_get_main_context (MetaThreadImpl *thread_impl); + +#endif /* META_THREAD_IMPL_H */ diff --git a/src/backends/native/meta-thread-private.h b/src/backends/native/meta-thread-private.h new file mode 100644 index 000000000..4387fdf06 --- /dev/null +++ b/src/backends/native/meta-thread-private.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_THREAD_PRIVATE_H +#define META_THREAD_PRIVATE_H + +#include "backends/native/meta-thread.h" + +#include "core/util-private.h" + +META_EXPORT_TEST +void meta_thread_class_register_impl_type (MetaThreadClass *thread_class, + GType impl_type); + +#endif /* META_THREAD_PRIVATE_H */ diff --git a/src/backends/native/meta-thread.c b/src/backends/native/meta-thread.c new file mode 100644 index 000000000..cd59efd72 --- /dev/null +++ b/src/backends/native/meta-thread.c @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2018-2021 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-thread-private.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-backend-types.h" +#include "backends/native/meta-thread-impl.h" + +enum +{ + PROP_0, + + PROP_BACKEND, + + N_PROPS +}; + +static GParamSpec *obj_props[N_PROPS]; + +typedef struct _MetaThreadCallbackData +{ + MetaThreadCallback callback; + gpointer user_data; + GDestroyNotify user_data_destroy; +} MetaThreadCallbackData; + +typedef struct _MetaThreadSimpleImplSource +{ + GSource source; + MetaThread *thread; +} MetaThreadSimpleImplSource; + +typedef struct _MetaThreadFdImplSource +{ + GSource source; + + gpointer fd_tag; + MetaThread *thread; + + MetaThreadTaskFunc dispatch; + gpointer user_data; +} MetaThreadFdImplSource; + +typedef struct _MetaThreadPrivate +{ + MetaBackend *backend; + + GMainContext *main_context; + + MetaThreadImpl *impl; + gboolean in_impl_task; + gboolean waiting_for_impl_task; + + GList *pending_callbacks; + guint callbacks_source_id; +} MetaThreadPrivate; + +typedef struct _MetaThreadClassPrivate +{ + GType impl_type; +} MetaThreadClassPrivate; + +G_DEFINE_TYPE_WITH_CODE (MetaThread, meta_thread, G_TYPE_OBJECT, + G_ADD_PRIVATE (MetaThread) + g_type_add_class_private (g_define_type_id, + sizeof (MetaThreadClassPrivate))) + +static void +meta_thread_callback_data_free (MetaThreadCallbackData *callback_data) +{ + if (callback_data->user_data_destroy) + callback_data->user_data_destroy (callback_data->user_data); + g_free (callback_data); +} + +static void +meta_thread_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaThread *thread = META_THREAD (object); + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + + switch (prop_id) + { + case PROP_BACKEND: + g_value_set_object (value, priv->backend); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_thread_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaThread *thread = META_THREAD (object); + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + + switch (prop_id) + { + case PROP_BACKEND: + priv->backend = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_thread_constructed (GObject *object) +{ + MetaThread *thread = META_THREAD (object); + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + MetaThreadClass *thread_class = META_THREAD_GET_CLASS (thread); + MetaThreadClassPrivate *class_priv = + G_TYPE_CLASS_GET_PRIVATE (thread_class, META_TYPE_THREAD, + MetaThreadClassPrivate); + + G_OBJECT_CLASS (meta_thread_parent_class)->constructed (object); + + priv->main_context = g_main_context_get_thread_default (); + + g_assert (g_type_is_a (class_priv->impl_type, META_TYPE_THREAD_IMPL)); + priv->impl = g_object_new (class_priv->impl_type, + "thread", thread, + NULL); +} + +static void +meta_thread_finalize (GObject *object) +{ + MetaThread *thread = META_THREAD (object); + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + + g_clear_list (&priv->pending_callbacks, + (GDestroyNotify) meta_thread_callback_data_free); + g_clear_handle_id (&priv->callbacks_source_id, g_source_remove); + + g_clear_object (&priv->impl); + + G_OBJECT_CLASS (meta_thread_parent_class)->finalize (object); +} + +static void +meta_thread_class_init (MetaThreadClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = meta_thread_get_property; + object_class->set_property = meta_thread_set_property; + object_class->constructed = meta_thread_constructed; + object_class->finalize = meta_thread_finalize; + + obj_props[PROP_BACKEND] = + g_param_spec_object ("backend", + "backend", + "MetaBackend", + META_TYPE_BACKEND, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPS, obj_props); +} + +static void +meta_thread_init (MetaThread *thread) +{ +} + +void +meta_thread_class_register_impl_type (MetaThreadClass *thread_class, + GType impl_type) +{ + MetaThreadClassPrivate *class_priv = + G_TYPE_CLASS_GET_PRIVATE (thread_class, META_TYPE_THREAD, + MetaThreadClassPrivate); + + g_assert (class_priv->impl_type == G_TYPE_INVALID); + class_priv->impl_type = impl_type; +} + +int +meta_thread_flush_callbacks (MetaThread *thread) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + GList *l; + int callback_count = 0; + + meta_assert_not_in_thread_impl (thread); + + for (l = priv->pending_callbacks; l; l = l->next) + { + MetaThreadCallbackData *callback_data = l->data; + + callback_data->callback (thread, callback_data->user_data); + meta_thread_callback_data_free (callback_data); + callback_count++; + } + + g_list_free (priv->pending_callbacks); + priv->pending_callbacks = NULL; + + return callback_count; +} + +static gboolean +callback_idle (gpointer user_data) +{ + MetaThread *thread = user_data; + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + + meta_thread_flush_callbacks (thread); + + priv->callbacks_source_id = 0; + return G_SOURCE_REMOVE; +} + +void +meta_thread_queue_callback (MetaThread *thread, + MetaThreadCallback callback, + gpointer user_data, + GDestroyNotify user_data_destroy) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + MetaThreadCallbackData *callback_data; + + callback_data = g_new0 (MetaThreadCallbackData, 1); + *callback_data = (MetaThreadCallbackData) { + .callback = callback, + .user_data = user_data, + .user_data_destroy = user_data_destroy, + }; + priv->pending_callbacks = g_list_append (priv->pending_callbacks, + callback_data); + if (!priv->callbacks_source_id) + { + GSource *idle_source; + + idle_source = g_idle_source_new (); + g_source_set_callback (idle_source, callback_idle, thread, NULL); + priv->callbacks_source_id = g_source_attach (idle_source, + priv->main_context); + g_source_unref (idle_source); + } +} + +gpointer +meta_thread_run_impl_task_sync (MetaThread *thread, + MetaThreadTaskFunc func, + gpointer user_data, + GError **error) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + gpointer ret; + + priv->in_impl_task = TRUE; + priv->waiting_for_impl_task = TRUE; + ret = func (priv->impl, user_data, error); + priv->waiting_for_impl_task = FALSE; + priv->in_impl_task = FALSE; + + return ret; +} + +static gboolean +simple_impl_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + MetaThreadSimpleImplSource *simple_impl_source = + (MetaThreadSimpleImplSource *) source; + MetaThread *thread = simple_impl_source->thread; + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + gboolean ret; + + priv->in_impl_task = TRUE; + ret = callback (user_data); + priv->in_impl_task = FALSE; + + return ret; +} + +static GSourceFuncs simple_impl_source_funcs = { + .dispatch = simple_impl_source_dispatch, +}; + +GSource * +meta_thread_add_source_in_impl (MetaThread *thread, + GSourceFunc func, + gpointer user_data, + GDestroyNotify user_data_destroy) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + GSource *source; + MetaThreadSimpleImplSource *simple_impl_source; + + meta_assert_in_thread_impl (thread); + + source = g_source_new (&simple_impl_source_funcs, + sizeof (MetaThreadSimpleImplSource)); + g_source_set_name (source, "[mutter] MetaThread simple impl"); + simple_impl_source = (MetaThreadSimpleImplSource *) source; + simple_impl_source->thread = thread; + + g_source_set_callback (source, func, user_data, user_data_destroy); + g_source_set_ready_time (source, 0); + g_source_attach (source, meta_thread_impl_get_main_context (priv->impl)); + + return source; +} + +static gboolean +meta_thread_fd_impl_source_check (GSource *source) +{ + MetaThreadFdImplSource *fd_impl_source = (MetaThreadFdImplSource *) source; + + return g_source_query_unix_fd (source, fd_impl_source->fd_tag) & G_IO_IN; +} + +static gboolean +meta_thread_fd_impl_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + MetaThreadFdImplSource *fd_impl_source = (MetaThreadFdImplSource *) source; + MetaThread *thread = fd_impl_source->thread; + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + gpointer ret; + GError *error = NULL; + + priv->in_impl_task = TRUE; + ret = fd_impl_source->dispatch (priv->impl, + fd_impl_source->user_data, + &error); + priv->in_impl_task = FALSE; + + if (!GPOINTER_TO_INT (ret)) + { + g_warning ("Failed to dispatch fd source: %s", error->message); + g_error_free (error); + } + + return G_SOURCE_CONTINUE; +} + +static GSourceFuncs fd_impl_source_funcs = { + NULL, + meta_thread_fd_impl_source_check, + meta_thread_fd_impl_source_dispatch +}; + +GSource * +meta_thread_register_fd_in_impl (MetaThread *thread, + int fd, + MetaThreadTaskFunc dispatch, + gpointer user_data) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + GSource *source; + MetaThreadFdImplSource *fd_impl_source; + + meta_assert_in_thread_impl (thread); + + source = g_source_new (&fd_impl_source_funcs, + sizeof (MetaThreadFdImplSource)); + g_source_set_name (source, "[mutter] MetaThread fd impl"); + fd_impl_source = (MetaThreadFdImplSource *) source; + fd_impl_source->dispatch = dispatch; + fd_impl_source->user_data = user_data; + fd_impl_source->thread = thread; + fd_impl_source->fd_tag = g_source_add_unix_fd (source, fd, + G_IO_IN | G_IO_ERR); + + g_source_attach (source, meta_thread_impl_get_main_context (priv->impl)); + + return source; +} + +MetaBackend * +meta_thread_get_backend (MetaThread *thread) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + + return priv->backend; +} + +gboolean +meta_thread_is_in_impl_task (MetaThread *thread) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + + return priv->in_impl_task; +} + +gboolean +meta_thread_is_waiting_for_impl_task (MetaThread *thread) +{ + MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); + + return priv->waiting_for_impl_task; +} diff --git a/src/backends/native/meta-thread.h b/src/backends/native/meta-thread.h new file mode 100644 index 000000000..2b973bfb0 --- /dev/null +++ b/src/backends/native/meta-thread.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2018-2021 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_THREAD_H +#define META_THREAD_H + +#include + +#include "backends/meta-backend-types.h" + +typedef struct _MetaThreadImpl MetaThreadImpl; + +#define META_TYPE_THREAD (meta_thread_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaThread, meta_thread, + META, THREAD, + GObject) + +struct _MetaThreadClass +{ + GObjectClass parent_class; +}; + +typedef void (* MetaThreadCallback) (MetaThread *thread, + gpointer user_data); + +typedef gpointer (* MetaThreadTaskFunc) (MetaThreadImpl *thread_impl, + gpointer user_data, + GError **error); + +void meta_thread_queue_callback (MetaThread *thread, + MetaThreadCallback callback, + gpointer user_data, + GDestroyNotify user_data_destroy); + +int meta_thread_flush_callbacks (MetaThread *thread); + +gpointer meta_thread_run_impl_task_sync (MetaThread *thread, + MetaThreadTaskFunc func, + gpointer user_data, + GError **error); + +GSource * meta_thread_add_source_in_impl (MetaThread *thread, + GSourceFunc func, + gpointer user_data, + GDestroyNotify user_data_destroy); + +GSource * meta_thread_register_fd_in_impl (MetaThread *thread, + int fd, + MetaThreadTaskFunc dispatch, + gpointer user_data); + +MetaBackend * meta_thread_get_backend (MetaThread *thread); + +gboolean meta_thread_is_in_impl_task (MetaThread *thread); + +gboolean meta_thread_is_waiting_for_impl_task (MetaThread *thread); + +#define meta_assert_in_thread_impl(thread) \ + g_assert (meta_thread_is_in_impl_task (thread)) +#define meta_assert_not_in_thread_impl(thread) \ + g_assert (!meta_thread_is_in_impl_task (thread)) +#define meta_assert_is_waiting_for_thread_impl_task(thread) \ + g_assert (meta_thread_is_waiting_for_impl_task (thread)) + +#endif /* META_THREAD_H */ diff --git a/src/meson.build b/src/meson.build index 91cd9d52c..b4025d5c6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -838,6 +838,11 @@ if have_native_backend 'backends/native/meta-seat-native.h', 'backends/native/meta-stage-native.c', 'backends/native/meta-stage-native.h', + 'backends/native/meta-thread-impl.c', + 'backends/native/meta-thread-impl.h', + 'backends/native/meta-thread.c', + 'backends/native/meta-thread.h', + 'backends/native/meta-thread-private.h', 'backends/native/meta-udev.c', 'backends/native/meta-udev.h', 'backends/native/meta-virtual-input-device-native.c', @@ -874,6 +879,7 @@ if have_native_backend 'backends/native/meta-backend-native-types.h', 'backends/native/meta-drm-buffer.h', 'backends/native/meta-kms-types.h', + 'backends/native/meta-thread.h', ] endif