From e4a8fc93a100dac9b52f22193c885430269af6c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 4 Jun 2022 22:45:17 +0200 Subject: [PATCH] thread: Add destroy notify function for post user data The destroy notify function can be called on any thread. Part-of: --- src/backends/native/meta-thread-impl.c | 5 ++++ src/backends/native/meta-thread-impl.h | 1 + src/backends/native/meta-thread.c | 7 +++--- src/backends/native/meta-thread.h | 1 + src/tests/native-thread.c | 34 +++++++++++++++++--------- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/backends/native/meta-thread-impl.c b/src/backends/native/meta-thread-impl.c index f0145dd2b..dd2041cbd 100644 --- a/src/backends/native/meta-thread-impl.c +++ b/src/backends/native/meta-thread-impl.c @@ -62,6 +62,7 @@ struct _MetaThreadTask { MetaThreadTaskFunc func; gpointer user_data; + GDestroyNotify user_data_destroy; MetaThreadTaskFeedbackFunc feedback_func; gpointer feedback_user_data; @@ -269,6 +270,7 @@ meta_thread_impl_get_main_context (MetaThreadImpl *thread_impl) MetaThreadTask * meta_thread_task_new (MetaThreadTaskFunc func, gpointer user_data, + GDestroyNotify user_data_destroy, MetaThreadTaskFeedbackFunc feedback_func, gpointer feedback_user_data, GMainContext *feedback_main_context) @@ -279,6 +281,7 @@ meta_thread_task_new (MetaThreadTaskFunc func, *task = (MetaThreadTask) { .func = func, .user_data = user_data, + .user_data_destroy = user_data_destroy, .feedback_func = feedback_func, .feedback_user_data = feedback_user_data, .feedback_main_context = feedback_main_context, @@ -290,6 +293,8 @@ meta_thread_task_new (MetaThreadTaskFunc func, void meta_thread_task_free (MetaThreadTask *task) { + if (task->user_data_destroy) + task->user_data_destroy (task->user_data); g_clear_error (&task->error); g_free (task); } diff --git a/src/backends/native/meta-thread-impl.h b/src/backends/native/meta-thread-impl.h index 164506f7f..0a8c2c2ef 100644 --- a/src/backends/native/meta-thread-impl.h +++ b/src/backends/native/meta-thread-impl.h @@ -75,6 +75,7 @@ gboolean meta_thread_impl_is_in_impl (MetaThreadImpl *thread_impl); MetaThreadTask * meta_thread_task_new (MetaThreadTaskFunc func, gpointer user_data, + GDestroyNotify user_data_destroy, MetaThreadTaskFeedbackFunc feedback_func, gpointer feedback_user_data, GMainContext *feedback_main_context); diff --git a/src/backends/native/meta-thread.c b/src/backends/native/meta-thread.c index b19d70ede..b686197e4 100644 --- a/src/backends/native/meta-thread.c +++ b/src/backends/native/meta-thread.c @@ -587,7 +587,7 @@ run_impl_task_sync_user (MetaThread *thread, MetaThreadTask *task; MetaSyncTaskData data = { 0 }; - task = meta_thread_task_new (func, user_data, + task = meta_thread_task_new (func, user_data, NULL, sync_task_done_user_in_impl, &data, meta_thread_impl_get_main_context (priv->impl)); meta_thread_impl_queue_task (priv->impl, task); @@ -636,7 +636,7 @@ run_impl_task_sync_kernel (MetaThread *thread, g_mutex_lock (&data.kernel.mutex); priv->waiting_for_impl_task = TRUE; - task = meta_thread_task_new (func, user_data, + task = meta_thread_task_new (func, user_data, NULL, sync_task_done_kernel_in_impl, &data, meta_thread_impl_get_main_context (priv->impl)); meta_thread_impl_queue_task (priv->impl, task); @@ -683,13 +683,14 @@ void meta_thread_post_impl_task (MetaThread *thread, MetaThreadTaskFunc func, gpointer user_data, + GDestroyNotify user_data_destroy, MetaThreadTaskFeedbackFunc feedback_func, gpointer feedback_user_data) { MetaThreadPrivate *priv = meta_thread_get_instance_private (thread); MetaThreadTask *task; - task = meta_thread_task_new (func, user_data, + task = meta_thread_task_new (func, user_data, user_data_destroy, feedback_func, feedback_user_data, g_main_context_get_thread_default ()); meta_thread_impl_queue_task (priv->impl, task); diff --git a/src/backends/native/meta-thread.h b/src/backends/native/meta-thread.h index 142c8c204..edc9421a8 100644 --- a/src/backends/native/meta-thread.h +++ b/src/backends/native/meta-thread.h @@ -82,6 +82,7 @@ META_EXPORT_TEST void meta_thread_post_impl_task (MetaThread *thread, MetaThreadTaskFunc func, gpointer user_data, + GDestroyNotify user_data_destroy, MetaThreadTaskFeedbackFunc feedback_func, gpointer feedback_user_data); diff --git a/src/tests/native-thread.c b/src/tests/native-thread.c index b73bf1433..921c4cb83 100644 --- a/src/tests/native-thread.c +++ b/src/tests/native-thread.c @@ -243,6 +243,18 @@ async_func (MetaThreadImpl *thread_impl, return GINT_TO_POINTER (TRUE); } +static void +async_destroy (gpointer user_data) +{ + AsyncData *async_data = user_data; + + g_mutex_lock (&async_data->mutex); + g_assert_cmpint (async_data->state, ==, 2); + async_data->state = 3; + g_main_loop_quit (async_data->loop); + g_mutex_unlock (&async_data->mutex); +} + static void async_feedback_func (gpointer retval, const GError *error, @@ -255,7 +267,6 @@ async_feedback_func (gpointer retval, g_mutex_lock (&async_data->mutex); g_assert_cmpint (async_data->state, ==, 1); async_data->state = 2; - g_main_loop_quit (async_data->loop); g_mutex_unlock (&async_data->mutex); } @@ -606,7 +617,8 @@ non_default_callback_thread_func (gpointer user_data) callback_data->thread_main_context); meta_thread_post_impl_task (callback_data->thread, - queue_non_default_callback_func, callback_data, + queue_non_default_callback_func, + callback_data, NULL, non_default_thread_feedback_func, callback_data); @@ -701,13 +713,13 @@ run_thread_tests (MetaThread *thread) async_data.thread = thread; async_data.loop = g_main_loop_new (NULL, FALSE); g_mutex_lock (&async_data.mutex); - meta_thread_post_impl_task (thread, async_func, &async_data, + meta_thread_post_impl_task (thread, async_func, &async_data, async_destroy, async_feedback_func, &async_data); g_assert_cmpint (async_data.state, ==, 0); g_mutex_unlock (&async_data.mutex); g_main_loop_run (async_data.loop); g_mutex_lock (&async_data.mutex); - g_assert_cmpint (async_data.state, ==, 2); + g_assert_cmpint (async_data.state, ==, 3); g_mutex_unlock (&async_data.mutex); g_main_loop_unref (async_data.loop); g_mutex_clear (&async_data.mutex); @@ -719,11 +731,11 @@ run_thread_tests (MetaThread *thread) async_data.thread = thread; async_data.loop = g_main_loop_new (NULL, FALSE); g_mutex_lock (&async_data.mutex); - meta_thread_post_impl_task (thread, multiple_async_func1, &async_data, + meta_thread_post_impl_task (thread, multiple_async_func1, &async_data, NULL, multiple_async_feedback_func1, &async_data); - meta_thread_post_impl_task (thread, multiple_async_func2, &async_data, + meta_thread_post_impl_task (thread, multiple_async_func2, &async_data, NULL, multiple_async_feedback_func2, &async_data); - meta_thread_post_impl_task (thread, multiple_async_func3, &async_data, + meta_thread_post_impl_task (thread, multiple_async_func3, &async_data, NULL, multiple_async_feedback_func3, &async_data); g_assert_cmpint (async_data.state, ==, 0); g_mutex_unlock (&async_data.mutex); @@ -740,7 +752,7 @@ run_thread_tests (MetaThread *thread) g_mutex_init (&mixed_data.mutex); mixed_data.thread = thread; g_mutex_lock (&mixed_data.mutex); - meta_thread_post_impl_task (thread, mixed_async_func, &mixed_data, + meta_thread_post_impl_task (thread, mixed_async_func, &mixed_data, NULL, mixed_async_feedback_func, &mixed_data); g_assert_cmpint (mixed_data.state, ==, 0); g_mutex_unlock (&mixed_data.mutex); @@ -780,7 +792,7 @@ run_thread_tests (MetaThread *thread) g_mutex_unlock (&flush_data1.init_mutex); meta_thread_post_impl_task (thread, queue_slow_callback, - &flush_data1, + &flush_data1, NULL, quit_main_loop_feedback_func, &loop_user); flush_data2 = (FlushData) { @@ -798,7 +810,7 @@ run_thread_tests (MetaThread *thread) g_mutex_unlock (&flush_data2.init_mutex); meta_thread_post_impl_task (thread, queue_slow_callback, - &flush_data2, + &flush_data2, NULL, quit_main_loop_feedback_func, &loop_user); @@ -918,7 +930,7 @@ meta_test_thread_late_callbacks_common (MetaThreadType thread_type) g_assert_nonnull (thread); g_assert_null (error); - meta_thread_post_impl_task (thread, late_callback, &done, NULL, NULL); + meta_thread_post_impl_task (thread, late_callback, &done, NULL, NULL, NULL); g_object_unref (thread); g_assert_null (thread);