[mutter] kms: Add API to post callbacks out of the impl context
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] kms: Add API to post callbacks out of the impl context
- Date: Thu, 20 Jun 2019 13:48:56 +0000 (UTC)
commit 2bbd2e55637430f011a35161e397f88b9dffd3c7
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Sun Mar 10 13:36:34 2019 +0100
kms: Add API to post callbacks out of the impl context
While the current impl context is in the same thread as the main
context, the separation still exists, and to post callbacks from the
impl context, it must pass MetaKms to make sure the callback is invoked
in the right context.
https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
src/backends/native/meta-kms-private.h | 8 +++++
src/backends/native/meta-kms.c | 66 ++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+)
---
diff --git a/src/backends/native/meta-kms-private.h b/src/backends/native/meta-kms-private.h
index da59d7431..8c0ce9425 100644
--- a/src/backends/native/meta-kms-private.h
+++ b/src/backends/native/meta-kms-private.h
@@ -24,10 +24,18 @@
#include "backends/native/meta-kms-types.h"
+typedef void (* MetaKmsCallback) (MetaKms *kms,
+ gpointer user_data);
+
typedef gboolean (* MetaKmsImplTaskFunc) (MetaKmsImpl *impl,
gpointer user_data,
GError **error);
+void meta_kms_queue_callback (MetaKms *kms,
+ MetaKmsCallback callback,
+ gpointer user_data,
+ GDestroyNotify user_data_destroy);
+
gboolean meta_kms_run_impl_task_sync (MetaKms *kms,
MetaKmsImplTaskFunc func,
gpointer user_data,
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index 4fd9c5ee4..408b9f5a2 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -27,6 +27,13 @@
#include "backends/native/meta-kms-impl-simple.h"
#include "backends/native/meta-udev.h"
+typedef struct _MetaKmsCallbackData
+{
+ MetaKmsCallback callback;
+ gpointer user_data;
+ GDestroyNotify user_data_destroy;
+} MetaKmsCallbackData;
+
struct _MetaKms
{
GObject parent;
@@ -39,10 +46,62 @@ struct _MetaKms
gboolean in_impl_task;
GList *devices;
+
+ GList *pending_callbacks;
+ guint callback_source_id;
};
G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
+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_slice_free (MetaKmsCallbackData, callback_data);
+}
+
+static gboolean
+callback_idle (gpointer user_data)
+{
+ MetaKms *kms = user_data;
+ GList *l;
+
+ 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);
+ }
+
+ g_list_free (kms->pending_callbacks);
+ kms->pending_callbacks = NULL;
+
+ kms->callback_source_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+void
+meta_kms_queue_callback (MetaKms *kms,
+ MetaKmsCallback callback,
+ gpointer user_data,
+ GDestroyNotify user_data_destroy)
+{
+ MetaKmsCallbackData *callback_data;
+
+ callback_data = g_slice_new0 (MetaKmsCallbackData);
+ *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);
+}
+
gboolean
meta_kms_run_impl_task_sync (MetaKms *kms,
MetaKmsImplTaskFunc func,
@@ -155,6 +214,13 @@ meta_kms_finalize (GObject *object)
MetaKms *kms = META_KMS (object);
MetaBackendNative *backend_native = META_BACKEND_NATIVE (kms->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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]