kms: Add API to add a GSource that'll be invoked in the impl context

The MetaKmsImpl implementation may need to add a GSource that should be
invoked in the right context; e.g. a idle callback, timeout etc. It
cannot just add it itself, since it's the responsibility of MetaKms to
determine what is the impl context and what is the main context, so add
API to MetaKms to ensure the callback is invoked correctly.

It's the responsibility of the caller to eventually remove and destroy
the GSource.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
This commit is contained in:
Jonas Ådahl 2019-03-10 13:40:30 +01:00 committed by Georges Basile Stavracas Neto
parent 2bbd2e5563
commit ca21ca6745
2 changed files with 52 additions and 0 deletions

View File

@ -41,6 +41,10 @@ gboolean meta_kms_run_impl_task_sync (MetaKms *kms,
gpointer user_data, gpointer user_data,
GError **error); GError **error);
GSource * meta_kms_add_source_in_impl (MetaKms *kms,
GSourceFunc func,
gpointer user_data);
gboolean meta_kms_in_impl_task (MetaKms *kms); gboolean meta_kms_in_impl_task (MetaKms *kms);
#define meta_assert_in_kms_impl(kms) \ #define meta_assert_in_kms_impl(kms) \

View File

@ -34,6 +34,12 @@ typedef struct _MetaKmsCallbackData
GDestroyNotify user_data_destroy; GDestroyNotify user_data_destroy;
} MetaKmsCallbackData; } MetaKmsCallbackData;
typedef struct _MetaKmsSimpleImplSource
{
GSource source;
MetaKms *kms;
} MetaKmsSimpleImplSource;
struct _MetaKms struct _MetaKms
{ {
GObject parent; GObject parent;
@ -117,6 +123,48 @@ meta_kms_run_impl_task_sync (MetaKms *kms,
return ret; return ret;
} }
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)
{
GSource *source;
MetaKmsSimpleImplSource *simple_impl_source;
meta_assert_in_kms_impl (kms);
source = g_source_new (&simple_impl_source_funcs,
sizeof (MetaKmsSimpleImplSource));
simple_impl_source = (MetaKmsSimpleImplSource *) source;
simple_impl_source->kms = kms;
g_source_set_callback (source, func, user_data, NULL);
g_source_attach (source, g_main_context_get_thread_default ());
return source;
}
gboolean gboolean
meta_kms_in_impl_task (MetaKms *kms) meta_kms_in_impl_task (MetaKms *kms)
{ {