diff --git a/src/backends/native/meta-thread-impl.c b/src/backends/native/meta-thread-impl.c index 977dc836d..a9acec247 100644 --- a/src/backends/native/meta-thread-impl.c +++ b/src/backends/native/meta-thread-impl.c @@ -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 diff --git a/src/backends/native/meta-thread-impl.h b/src/backends/native/meta-thread-impl.h index 83fd36493..c3b8c6449 100644 --- a/src/backends/native/meta-thread-impl.h +++ b/src/backends/native/meta-thread-impl.h @@ -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); diff --git a/src/backends/native/meta-thread.c b/src/backends/native/meta-thread.c index a6e7ab1d7..0db2f7bda 100644 --- a/src/backends/native/meta-thread.c +++ b/src/backends/native/meta-thread.c @@ -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); diff --git a/src/tests/native-thread.c b/src/tests/native-thread.c index 3733af957..53a70d26a 100644 --- a/src/tests/native-thread.c +++ b/src/tests/native-thread.c @@ -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