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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
This commit is contained in:
parent
7fea24d585
commit
a6baa77eab
14 changed files with 843 additions and 346 deletions
|
@ -232,9 +232,9 @@ meta_kms_device_get_fallback_modes (MetaKmsDevice *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
disable_device_in_impl (MetaKmsImpl *impl,
|
disable_device_in_impl (MetaThreadImpl *thread_impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaKmsImplDevice *impl_device = user_data;
|
MetaKmsImplDevice *impl_device = user_data;
|
||||||
|
|
||||||
|
@ -289,9 +289,9 @@ typedef struct
|
||||||
} PostUpdateData;
|
} PostUpdateData;
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
process_update_in_impl (MetaKmsImpl *impl,
|
process_update_in_impl (MetaThreadImpl *thread_impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
PostUpdateData *data = user_data;
|
PostUpdateData *data = user_data;
|
||||||
MetaKmsUpdate *update = data->update;
|
MetaKmsUpdate *update = data->update;
|
||||||
|
@ -484,10 +484,11 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
create_impl_device_in_impl (MetaKmsImpl *impl,
|
create_impl_device_in_impl (MetaThreadImpl *thread_impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaKmsImpl *impl = META_KMS_IMPL (thread_impl);
|
||||||
CreateImplDeviceData *data = user_data;
|
CreateImplDeviceData *data = user_data;
|
||||||
MetaKmsImplDevice *impl_device;
|
MetaKmsImplDevice *impl_device;
|
||||||
|
|
||||||
|
@ -561,9 +562,9 @@ meta_kms_device_new (MetaKms *kms,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
free_impl_device_in_impl (MetaKmsImpl *impl,
|
free_impl_device_in_impl (MetaThreadImpl *thread_impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaKmsImplDevice *impl_device = user_data;
|
MetaKmsImplDevice *impl_device = user_data;
|
||||||
|
|
||||||
|
|
|
@ -248,9 +248,9 @@ meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
kms_event_dispatch_in_impl (MetaKmsImpl *impl,
|
kms_event_dispatch_in_impl (MetaThreadImpl *impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaKmsImplDevice *impl_device = user_data;
|
MetaKmsImplDevice *impl_device = user_data;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
@ -992,12 +992,12 @@ meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_resources_changed_callback (MetaKms *kms,
|
emit_resources_changed_callback (MetaThread *thread,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaKmsResourceChanges changes = GPOINTER_TO_UINT (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
|
static void
|
||||||
|
|
|
@ -26,13 +26,6 @@
|
||||||
#include "backends/native/meta-kms-device-private.h"
|
#include "backends/native/meta-kms-device-private.h"
|
||||||
#include "backends/native/meta-kms-update-private.h"
|
#include "backends/native/meta-kms-update-private.h"
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PROP_0,
|
|
||||||
|
|
||||||
PROP_KMS,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaKmsImpl
|
struct _MetaKmsImpl
|
||||||
{
|
{
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
@ -40,19 +33,17 @@ struct _MetaKmsImpl
|
||||||
|
|
||||||
typedef struct _MetaKmsImplPrivate
|
typedef struct _MetaKmsImplPrivate
|
||||||
{
|
{
|
||||||
MetaKms *kms;
|
|
||||||
|
|
||||||
GList *impl_devices;
|
GList *impl_devices;
|
||||||
} MetaKmsImplPrivate;
|
} 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 *
|
MetaKms *
|
||||||
meta_kms_impl_get_kms (MetaKmsImpl *impl)
|
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
|
void
|
||||||
|
@ -61,7 +52,7 @@ meta_kms_impl_add_impl_device (MetaKmsImpl *impl,
|
||||||
{
|
{
|
||||||
MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (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);
|
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);
|
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);
|
priv->impl_devices = g_list_remove (priv->impl_devices, impl_device);
|
||||||
}
|
}
|
||||||
|
@ -120,46 +111,6 @@ meta_kms_impl_new (MetaKms *kms)
|
||||||
NULL);
|
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
|
static void
|
||||||
meta_kms_impl_init (MetaKmsImpl *kms_impl)
|
meta_kms_impl_init (MetaKmsImpl *kms_impl)
|
||||||
{
|
{
|
||||||
|
@ -168,20 +119,4 @@ meta_kms_impl_init (MetaKmsImpl *kms_impl)
|
||||||
static void
|
static void
|
||||||
meta_kms_impl_class_init (MetaKmsImplClass *klass)
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,11 @@
|
||||||
#include "backends/native/meta-kms-impl-device.h"
|
#include "backends/native/meta-kms-impl-device.h"
|
||||||
#include "backends/native/meta-kms-page-flip-private.h"
|
#include "backends/native/meta-kms-page-flip-private.h"
|
||||||
#include "backends/native/meta-kms.h"
|
#include "backends/native/meta-kms.h"
|
||||||
|
#include "backends/native/meta-thread-impl.h"
|
||||||
|
|
||||||
#define META_TYPE_KMS_IMPL (meta_kms_impl_get_type ())
|
#define META_TYPE_KMS_IMPL (meta_kms_impl_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (MetaKmsImpl, meta_kms_impl,
|
G_DECLARE_FINAL_TYPE (MetaKmsImpl, meta_kms_impl,
|
||||||
META, KMS_IMPL, GObject)
|
META, KMS_IMPL, MetaThreadImpl)
|
||||||
|
|
||||||
MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl);
|
MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl);
|
||||||
|
|
||||||
|
|
|
@ -142,13 +142,13 @@ meta_kms_page_flip_data_get_crtc (MetaKmsPageFlipData *page_flip_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_kms_page_flip_data_flipped (MetaKms *kms,
|
meta_kms_page_flip_data_flipped (MetaThread *thread,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipData *page_flip_data = user_data;
|
MetaKmsPageFlipData *page_flip_data = user_data;
|
||||||
GList *l;
|
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)
|
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
|
static void
|
||||||
meta_kms_page_flip_data_mode_set_fallback (MetaKms *kms,
|
meta_kms_page_flip_data_mode_set_fallback (MetaThread *thread,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipData *page_flip_data = user_data;
|
MetaKmsPageFlipData *page_flip_data = user_data;
|
||||||
GList *l;
|
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)
|
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
|
static void
|
||||||
meta_kms_page_flip_data_discard (MetaKms *kms,
|
meta_kms_page_flip_data_discard (MetaThread *thread,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipData *page_flip_data = user_data;
|
MetaKmsPageFlipData *page_flip_data = user_data;
|
||||||
GList *l;
|
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)
|
for (l = page_flip_data->closures; l; l = l->next)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,32 +30,28 @@
|
||||||
typedef void (* MetaKmsCallback) (MetaKms *kms,
|
typedef void (* MetaKmsCallback) (MetaKms *kms,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
typedef gpointer (* MetaKmsImplTaskFunc) (MetaKmsImpl *impl,
|
void meta_kms_queue_callback (MetaKms *kms,
|
||||||
gpointer user_data,
|
MetaThreadCallback callback,
|
||||||
GError **error);
|
gpointer user_data,
|
||||||
|
GDestroyNotify user_data_destroy);
|
||||||
void meta_kms_queue_callback (MetaKms *kms,
|
|
||||||
MetaKmsCallback callback,
|
|
||||||
gpointer user_data,
|
|
||||||
GDestroyNotify user_data_destroy);
|
|
||||||
|
|
||||||
void meta_kms_queue_result_callback (MetaKms *kms,
|
void meta_kms_queue_result_callback (MetaKms *kms,
|
||||||
MetaKmsResultListener *listener);
|
MetaKmsResultListener *listener);
|
||||||
|
|
||||||
gpointer meta_kms_run_impl_task_sync (MetaKms *kms,
|
gpointer meta_kms_run_impl_task_sync (MetaKms *kms,
|
||||||
MetaKmsImplTaskFunc func,
|
MetaThreadTaskFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
GSource * meta_kms_add_source_in_impl (MetaKms *kms,
|
GSource * meta_kms_add_source_in_impl (MetaKms *kms,
|
||||||
GSourceFunc func,
|
GSourceFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_data_destroy);
|
GDestroyNotify user_data_destroy);
|
||||||
|
|
||||||
GSource * meta_kms_register_fd_in_impl (MetaKms *kms,
|
GSource * meta_kms_register_fd_in_impl (MetaKms *kms,
|
||||||
int fd,
|
int fd,
|
||||||
MetaKmsImplTaskFunc dispatch,
|
MetaThreadTaskFunc dispatch,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
MetaKmsResourceChanges meta_kms_update_states_sync (MetaKms *kms,
|
MetaKmsResourceChanges meta_kms_update_states_sync (MetaKms *kms,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "backends/native/meta-kms-device-private.h"
|
#include "backends/native/meta-kms-device-private.h"
|
||||||
#include "backends/native/meta-kms-impl.h"
|
#include "backends/native/meta-kms-impl.h"
|
||||||
#include "backends/native/meta-kms-update-private.h"
|
#include "backends/native/meta-kms-update-private.h"
|
||||||
|
#include "backends/native/meta-thread-private.h"
|
||||||
#include "backends/native/meta-udev.h"
|
#include "backends/native/meta-udev.h"
|
||||||
#include "cogl/cogl.h"
|
#include "cogl/cogl.h"
|
||||||
|
|
||||||
|
@ -132,38 +133,12 @@ enum
|
||||||
|
|
||||||
static int signals[N_SIGNALS];
|
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
|
struct _MetaKms
|
||||||
{
|
{
|
||||||
GObject parent;
|
MetaThread parent;
|
||||||
|
|
||||||
MetaKmsFlags flags;
|
MetaKmsFlags flags;
|
||||||
|
|
||||||
MetaBackend *backend;
|
|
||||||
|
|
||||||
gulong hotplug_handler_id;
|
gulong hotplug_handler_id;
|
||||||
gulong removed_handler_id;
|
gulong removed_handler_id;
|
||||||
|
|
||||||
|
@ -179,11 +154,11 @@ struct _MetaKms
|
||||||
guint callback_source_id;
|
guint callback_source_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (MetaKms, meta_kms, META_TYPE_THREAD)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
invoke_result_listener (MetaKms *kms,
|
invoke_result_listener (MetaThread *thread,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaKmsResultListener *listener = user_data;
|
MetaKmsResultListener *listener = user_data;
|
||||||
|
|
||||||
|
@ -201,10 +176,12 @@ meta_kms_queue_result_callback (MetaKms *kms,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
meta_kms_discard_pending_page_flips_in_impl (MetaKmsImpl *impl,
|
meta_kms_discard_pending_page_flips_in_impl (MetaThreadImpl *thread_impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaKmsImpl *impl = META_KMS_IMPL (thread_impl);
|
||||||
|
|
||||||
meta_kms_impl_discard_pending_page_flips (impl);
|
meta_kms_impl_discard_pending_page_flips (impl);
|
||||||
return GINT_TO_POINTER (TRUE);
|
return GINT_TO_POINTER (TRUE);
|
||||||
}
|
}
|
||||||
|
@ -219,10 +196,12 @@ meta_kms_discard_pending_page_flips (MetaKms *kms)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
meta_kms_notify_modes_set_in_impl (MetaKmsImpl *impl,
|
meta_kms_notify_modes_set_in_impl (MetaThreadImpl *thread_impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaKmsImpl *impl = META_KMS_IMPL (thread_impl);
|
||||||
|
|
||||||
meta_kms_impl_notify_modes_set (impl);
|
meta_kms_impl_notify_modes_set (impl);
|
||||||
return GINT_TO_POINTER (TRUE);
|
return GINT_TO_POINTER (TRUE);
|
||||||
}
|
}
|
||||||
|
@ -230,212 +209,73 @@ meta_kms_notify_modes_set_in_impl (MetaKmsImpl *impl,
|
||||||
void
|
void
|
||||||
meta_kms_notify_modes_set (MetaKms *kms)
|
meta_kms_notify_modes_set (MetaKms *kms)
|
||||||
{
|
{
|
||||||
meta_kms_run_impl_task_sync (kms,
|
MetaThread *thread = META_THREAD (kms);
|
||||||
meta_kms_notify_modes_set_in_impl,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
meta_thread_run_impl_task_sync (thread,
|
||||||
meta_kms_callback_data_free (MetaKmsCallbackData *callback_data)
|
meta_kms_notify_modes_set_in_impl,
|
||||||
{
|
NULL,
|
||||||
if (callback_data->user_data_destroy)
|
NULL);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_kms_queue_callback (MetaKms *kms,
|
meta_kms_queue_callback (MetaKms *kms,
|
||||||
MetaKmsCallback callback,
|
MetaThreadCallback callback,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_data_destroy)
|
GDestroyNotify user_data_destroy)
|
||||||
{
|
{
|
||||||
MetaKmsCallbackData *callback_data;
|
MetaThread *thread = META_THREAD (kms);
|
||||||
|
|
||||||
callback_data = g_new0 (MetaKmsCallbackData, 1);
|
meta_thread_queue_callback (thread, callback, user_data, user_data_destroy);
|
||||||
*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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
meta_kms_run_impl_task_sync (MetaKms *kms,
|
meta_kms_run_impl_task_sync (MetaKms *kms,
|
||||||
MetaKmsImplTaskFunc func,
|
MetaThreadTaskFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gpointer ret;
|
MetaThread *thread = META_THREAD (kms);
|
||||||
|
|
||||||
kms->in_impl_task = TRUE;
|
return meta_thread_run_impl_task_sync (thread, func, user_data, error);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *
|
GSource *
|
||||||
meta_kms_add_source_in_impl (MetaKms *kms,
|
meta_kms_add_source_in_impl (MetaKms *kms,
|
||||||
GSourceFunc func,
|
GSourceFunc func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_data_destroy)
|
GDestroyNotify user_data_destroy)
|
||||||
{
|
{
|
||||||
GSource *source;
|
MetaThread *thread = META_THREAD (kms);
|
||||||
MetaKmsSimpleImplSource *simple_impl_source;
|
|
||||||
|
|
||||||
meta_assert_in_kms_impl (kms);
|
return meta_thread_add_source_in_impl (thread, func,
|
||||||
|
user_data, user_data_destroy);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *
|
GSource *
|
||||||
meta_kms_register_fd_in_impl (MetaKms *kms,
|
meta_kms_register_fd_in_impl (MetaKms *kms,
|
||||||
int fd,
|
int fd,
|
||||||
MetaKmsImplTaskFunc dispatch,
|
MetaThreadTaskFunc dispatch,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GSource *source;
|
MetaThread *thread = META_THREAD (kms);
|
||||||
MetaKmsFdImplSource *fd_impl_source;
|
|
||||||
|
|
||||||
meta_assert_in_kms_impl (kms);
|
return meta_thread_register_fd_in_impl (thread, fd, dispatch, user_data);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_kms_in_impl_task (MetaKms *kms)
|
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
|
gboolean
|
||||||
meta_kms_is_waiting_for_impl_task (MetaKms *kms)
|
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
|
typedef struct _UpdateStatesData
|
||||||
|
@ -488,11 +328,12 @@ meta_kms_update_states_in_impl (MetaKms *kms,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
update_states_in_impl (MetaKmsImpl *impl,
|
update_states_in_impl (MetaThreadImpl *thread_impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
UpdateStatesData *data = user_data;
|
UpdateStatesData *data = user_data;
|
||||||
|
MetaKmsImpl *impl = META_KMS_IMPL (thread_impl);
|
||||||
MetaKms *kms = meta_kms_impl_get_kms (impl);
|
MetaKms *kms = meta_kms_impl_get_kms (impl);
|
||||||
|
|
||||||
return GUINT_TO_POINTER (meta_kms_update_states_in_impl (kms, data));
|
return GUINT_TO_POINTER (meta_kms_update_states_in_impl (kms, data));
|
||||||
|
@ -557,7 +398,7 @@ on_udev_device_removed (MetaUdev *udev,
|
||||||
MetaBackend *
|
MetaBackend *
|
||||||
meta_kms_get_backend (MetaKms *kms)
|
meta_kms_get_backend (MetaKms *kms)
|
||||||
{
|
{
|
||||||
return kms->backend;
|
return meta_thread_get_backend (META_THREAD (kms));
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *
|
GList *
|
||||||
|
@ -587,10 +428,12 @@ meta_kms_create_device (MetaKms *kms,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
prepare_shutdown_in_impl (MetaKmsImpl *impl,
|
prepare_shutdown_in_impl (MetaThreadImpl *thread_impl,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaKmsImpl *impl = META_KMS_IMPL (thread_impl);
|
||||||
|
|
||||||
meta_kms_impl_prepare_shutdown (impl);
|
meta_kms_impl_prepare_shutdown (impl);
|
||||||
return GINT_TO_POINTER (TRUE);
|
return GINT_TO_POINTER (TRUE);
|
||||||
}
|
}
|
||||||
|
@ -600,7 +443,7 @@ on_prepare_shutdown (MetaBackend *backend,
|
||||||
MetaKms *kms)
|
MetaKms *kms)
|
||||||
{
|
{
|
||||||
meta_kms_run_impl_task_sync (kms, prepare_shutdown_in_impl, NULL, NULL);
|
meta_kms_run_impl_task_sync (kms, prepare_shutdown_in_impl, NULL, NULL);
|
||||||
flush_callbacks (kms);
|
meta_thread_flush_callbacks (META_THREAD (kms));
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaKms *
|
MetaKms *
|
||||||
|
@ -612,15 +455,10 @@ meta_kms_new (MetaBackend *backend,
|
||||||
MetaUdev *udev = meta_backend_native_get_udev (backend_native);
|
MetaUdev *udev = meta_backend_native_get_udev (backend_native);
|
||||||
MetaKms *kms;
|
MetaKms *kms;
|
||||||
|
|
||||||
kms = g_object_new (META_TYPE_KMS, NULL);
|
kms = g_object_new (META_TYPE_KMS,
|
||||||
|
"backend", backend,
|
||||||
|
NULL);
|
||||||
kms->flags = flags;
|
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))
|
if (!(flags & META_KMS_FLAG_NO_MODE_SETTING))
|
||||||
{
|
{
|
||||||
|
@ -643,15 +481,9 @@ static void
|
||||||
meta_kms_finalize (GObject *object)
|
meta_kms_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
MetaKms *kms = META_KMS (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);
|
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);
|
g_list_free_full (kms->devices, g_object_unref);
|
||||||
|
|
||||||
|
@ -675,6 +507,7 @@ static void
|
||||||
meta_kms_class_init (MetaKmsClass *klass)
|
meta_kms_class_init (MetaKmsClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
MetaThreadClass *thread_class = META_THREAD_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = meta_kms_finalize;
|
object_class->finalize = meta_kms_finalize;
|
||||||
object_class->constructed = meta_kms_constructed;
|
object_class->constructed = meta_kms_constructed;
|
||||||
|
@ -687,6 +520,8 @@ meta_kms_class_init (MetaKmsClass *klass)
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 1,
|
||||||
META_TYPE_KMS_RESOURCE_CHANGES);
|
META_TYPE_KMS_RESOURCE_CHANGES);
|
||||||
|
|
||||||
|
meta_thread_class_register_impl_type (thread_class, META_TYPE_KMS_IMPL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/native/meta-kms-types.h"
|
#include "backends/native/meta-kms-types.h"
|
||||||
|
#include "backends/native/meta-thread.h"
|
||||||
|
|
||||||
typedef enum _MetaKmsFlags
|
typedef enum _MetaKmsFlags
|
||||||
{
|
{
|
||||||
|
@ -32,7 +33,7 @@ typedef enum _MetaKmsFlags
|
||||||
} MetaKmsFlags;
|
} MetaKmsFlags;
|
||||||
|
|
||||||
#define META_TYPE_KMS (meta_kms_get_type ())
|
#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);
|
void meta_kms_discard_pending_page_flips (MetaKms *kms);
|
||||||
|
|
||||||
|
|
142
src/backends/native/meta-thread-impl.c
Normal file
142
src/backends/native/meta-thread-impl.c
Normal file
|
@ -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 <glib-object.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
40
src/backends/native/meta-thread-impl.h
Normal file
40
src/backends/native/meta-thread-impl.h
Normal file
|
@ -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 <glib-object.h>
|
||||||
|
|
||||||
|
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 */
|
31
src/backends/native/meta-thread-private.h
Normal file
31
src/backends/native/meta-thread-private.h
Normal file
|
@ -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 */
|
428
src/backends/native/meta-thread.c
Normal file
428
src/backends/native/meta-thread.c
Normal file
|
@ -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;
|
||||||
|
}
|
81
src/backends/native/meta-thread.h
Normal file
81
src/backends/native/meta-thread.h
Normal file
|
@ -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 <glib-object.h>
|
||||||
|
|
||||||
|
#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 */
|
|
@ -838,6 +838,11 @@ if have_native_backend
|
||||||
'backends/native/meta-seat-native.h',
|
'backends/native/meta-seat-native.h',
|
||||||
'backends/native/meta-stage-native.c',
|
'backends/native/meta-stage-native.c',
|
||||||
'backends/native/meta-stage-native.h',
|
'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.c',
|
||||||
'backends/native/meta-udev.h',
|
'backends/native/meta-udev.h',
|
||||||
'backends/native/meta-virtual-input-device-native.c',
|
'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-backend-native-types.h',
|
||||||
'backends/native/meta-drm-buffer.h',
|
'backends/native/meta-drm-buffer.h',
|
||||||
'backends/native/meta-kms-types.h',
|
'backends/native/meta-kms-types.h',
|
||||||
|
'backends/native/meta-thread.h',
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue