mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 19:40:43 -05:00
thread: Flush tasks and callbacks on finalize
This will make sure no tasks or callbacks are unexpectedly dropped, potentially leaking or leaving things in an unexpected state. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
This commit is contained in:
parent
261624538c
commit
251722ec4e
@ -454,7 +454,7 @@ invoke_task_feedback (MetaThread *thread,
|
|||||||
task->feedback_func (task->retval, task->error, task->feedback_user_data);
|
task->feedback_func (task->retval, task->error, task->feedback_user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
|
meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
|
||||||
{
|
{
|
||||||
MetaThreadImplPrivate *priv =
|
MetaThreadImplPrivate *priv =
|
||||||
@ -463,7 +463,9 @@ meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
|
|||||||
gpointer retval;
|
gpointer retval;
|
||||||
g_autoptr (GError) error = NULL;
|
g_autoptr (GError) error = NULL;
|
||||||
|
|
||||||
task = g_async_queue_pop (priv->task_queue);
|
task = g_async_queue_try_pop (priv->task_queue);
|
||||||
|
if (!task)
|
||||||
|
return 0;
|
||||||
|
|
||||||
priv->in_impl_task = TRUE;
|
priv->in_impl_task = TRUE;
|
||||||
retval = task->func (thread_impl, task->user_data, &error);
|
retval = task->func (thread_impl, task->user_data, &error);
|
||||||
@ -489,6 +491,8 @@ meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
|
|||||||
g_clear_pointer (&task, meta_thread_task_free);
|
g_clear_pointer (&task, meta_thread_task_free);
|
||||||
|
|
||||||
priv->in_impl_task = FALSE;
|
priv->in_impl_task = FALSE;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -65,7 +65,7 @@ GSource * meta_thread_impl_register_fd (MetaThreadImpl *thread_impl,
|
|||||||
void meta_thread_impl_queue_task (MetaThreadImpl *thread_impl,
|
void meta_thread_impl_queue_task (MetaThreadImpl *thread_impl,
|
||||||
MetaThreadTask *task);
|
MetaThreadTask *task);
|
||||||
|
|
||||||
void meta_thread_impl_dispatch (MetaThreadImpl *thread_impl);
|
int meta_thread_impl_dispatch (MetaThreadImpl *thread_impl);
|
||||||
|
|
||||||
gboolean meta_thread_impl_is_in_impl (MetaThreadImpl *thread_impl);
|
gboolean meta_thread_impl_is_in_impl (MetaThreadImpl *thread_impl);
|
||||||
|
|
||||||
|
@ -156,8 +156,8 @@ meta_thread_finalize (GObject *object)
|
|||||||
MetaThread *thread = META_THREAD (object);
|
MetaThread *thread = META_THREAD (object);
|
||||||
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||||
|
|
||||||
g_clear_list (&priv->pending_callbacks,
|
while (meta_thread_impl_dispatch (priv->impl) > 0);
|
||||||
(GDestroyNotify) meta_thread_callback_data_free);
|
meta_thread_flush_callbacks (thread);
|
||||||
g_clear_handle_id (&priv->callbacks_source_id, g_source_remove);
|
g_clear_handle_id (&priv->callbacks_source_id, g_source_remove);
|
||||||
|
|
||||||
g_clear_object (&priv->impl);
|
g_clear_object (&priv->impl);
|
||||||
|
@ -566,11 +566,48 @@ meta_test_thread_user_common (void)
|
|||||||
test_thread = NULL;
|
test_thread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
late_callback (MetaThreadImpl *thread_impl,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gboolean *done = user_data;
|
||||||
|
|
||||||
|
*done = TRUE;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_test_thread_user_late_callbacks (void)
|
||||||
|
{
|
||||||
|
MetaBackend *backend = meta_context_get_backend (test_context);
|
||||||
|
MetaThread *thread;
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
gboolean done = FALSE;
|
||||||
|
|
||||||
|
thread = g_initable_new (META_TYPE_THREAD_TEST,
|
||||||
|
NULL, &error,
|
||||||
|
"backend", backend,
|
||||||
|
NULL);
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (thread), (gpointer *) &thread);
|
||||||
|
g_assert_nonnull (thread);
|
||||||
|
g_assert_null (error);
|
||||||
|
|
||||||
|
meta_thread_post_impl_task (thread, late_callback, &done, NULL, NULL);
|
||||||
|
|
||||||
|
g_object_unref (thread);
|
||||||
|
g_assert_null (thread);
|
||||||
|
g_assert_true (done);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_tests (void)
|
init_tests (void)
|
||||||
{
|
{
|
||||||
g_test_add_func ("/backends/native/thread/user/common",
|
g_test_add_func ("/backends/native/thread/user/common",
|
||||||
meta_test_thread_user_common);
|
meta_test_thread_user_common);
|
||||||
|
g_test_add_func ("/backends/native/thread/user/late-callbacks",
|
||||||
|
meta_test_thread_user_late_callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
Reference in New Issue
Block a user