thread/impl: Add 'reset' signal

This signal is emitted before terminating the thread, but also when
resetting the thread type. This is to allow thread implementations to
make sure they have no stale pending callbacks to any old main contexts.

This commit "terminates" the impl thread even if there is no actual
thread; this is to trigger the "reset" signal, also when switching from
a user thread to a kernel thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
This commit is contained in:
Jonas Ådahl 2022-12-21 17:24:41 +01:00
parent bedec579b8
commit 2617bd8e72
2 changed files with 19 additions and 0 deletions

View File

@ -27,6 +27,15 @@
#define META_THREAD_IMPL_TERMINATE ((gpointer) 1) #define META_THREAD_IMPL_TERMINATE ((gpointer) 1)
enum
{
RESET,
N_SIGNALS
};
static guint signals[N_SIGNALS];
enum enum
{ {
PROP_0, PROP_0,
@ -252,6 +261,14 @@ meta_thread_impl_class_init (MetaThreadImplClass *klass)
G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS); G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, obj_props); g_object_class_install_properties (object_class, N_PROPS, obj_props);
signals[RESET] =
g_signal_new ("reset",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
} }
static void static void
@ -517,6 +534,7 @@ meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
if (task == META_THREAD_IMPL_TERMINATE) if (task == META_THREAD_IMPL_TERMINATE)
{ {
g_signal_emit (thread_impl, signals[RESET], 0);
if (priv->loop) if (priv->loop)
g_main_loop_quit (priv->loop); g_main_loop_quit (priv->loop);
return 0; return 0;

View File

@ -534,6 +534,7 @@ finalize_thread_user (MetaThread *thread)
{ {
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
meta_thread_impl_terminate (priv->impl);
while (meta_thread_impl_dispatch (priv->impl) > 0); while (meta_thread_impl_dispatch (priv->impl) > 0);
unwrap_main_context (thread, meta_thread_impl_get_main_context (priv->impl)); unwrap_main_context (thread, meta_thread_impl_get_main_context (priv->impl));
} }