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);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
|
||||
{
|
||||
MetaThreadImplPrivate *priv =
|
||||
@ -463,7 +463,9 @@ meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
|
||||
gpointer retval;
|
||||
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;
|
||||
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);
|
||||
|
||||
priv->in_impl_task = FALSE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -65,7 +65,7 @@ GSource * meta_thread_impl_register_fd (MetaThreadImpl *thread_impl,
|
||||
void meta_thread_impl_queue_task (MetaThreadImpl *thread_impl,
|
||||
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);
|
||||
|
||||
|
@ -156,8 +156,8 @@ 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);
|
||||
while (meta_thread_impl_dispatch (priv->impl) > 0);
|
||||
meta_thread_flush_callbacks (thread);
|
||||
g_clear_handle_id (&priv->callbacks_source_id, g_source_remove);
|
||||
|
||||
g_clear_object (&priv->impl);
|
||||
|
@ -566,11 +566,48 @@ meta_test_thread_user_common (void)
|
||||
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
|
||||
init_tests (void)
|
||||
{
|
||||
g_test_add_func ("/backends/native/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
|
||||
|
Loading…
Reference in New Issue
Block a user