2 * Copyright 2012-2019 Red Hat, Inc.
4 * SPDX-License-Identifier: LGPL-2.1-or-later
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * See the included COPYING file for more information.
17 static GMainLoop *loop;
18 static GThread *main_thread;
21 /* We need objects for a few tests where we don't care what type
22 * they are, just that they're GObjects.
24 #define g_dummy_object_new g_socket_client_new
27 idle_quit_loop (gpointer user_data)
29 g_main_loop_quit (loop);
34 completed_cb (GObject *gobject,
38 gboolean *notification_emitted = user_data;
39 *notification_emitted = TRUE;
43 wait_for_completed_notification (GTask *task)
45 gboolean notification_emitted = FALSE;
46 gboolean is_completed = FALSE;
48 /* Hold a ref. so we can check the :completed property afterwards. */
51 g_signal_connect (task, "notify::completed",
52 (GCallback) completed_cb, ¬ification_emitted);
53 g_idle_add (idle_quit_loop, NULL);
54 g_main_loop_run (loop);
55 g_assert_true (notification_emitted);
57 g_assert_true (g_task_get_completed (task));
58 g_object_get (G_OBJECT (task), "completed", &is_completed, NULL);
59 g_assert_true (is_completed);
61 g_object_unref (task);
67 basic_callback (GObject *object,
71 gssize *result_out = user_data;
74 g_assert (object == NULL);
75 g_assert (g_task_is_valid (result, object));
76 g_assert (g_async_result_get_user_data (result) == user_data);
77 g_assert (!g_task_had_error (G_TASK (result)));
78 g_assert_false (g_task_get_completed (G_TASK (result)));
80 *result_out = g_task_propagate_int (G_TASK (result), &error);
81 g_assert_no_error (error);
83 g_assert (!g_task_had_error (G_TASK (result)));
85 g_main_loop_quit (loop);
89 basic_return (gpointer user_data)
91 GTask *task = user_data;
93 g_task_return_int (task, magic);
94 g_object_unref (task);
100 basic_destroy_notify (gpointer user_data)
102 gboolean *destroyed = user_data;
112 gboolean task_data_destroyed = FALSE;
113 gboolean notification_emitted = FALSE;
115 task = g_task_new (NULL, NULL, basic_callback, &result);
116 g_task_set_task_data (task, &task_data_destroyed, basic_destroy_notify);
117 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
118 g_signal_connect (task, "notify::completed",
119 (GCallback) completed_cb, ¬ification_emitted);
121 g_idle_add (basic_return, task);
122 g_main_loop_run (loop);
124 g_assert_cmpint (result, ==, magic);
125 g_assert (task_data_destroyed == TRUE);
126 g_assert_true (notification_emitted);
127 g_assert (task == NULL);
133 error_callback (GObject *object,
134 GAsyncResult *result,
137 gssize *result_out = user_data;
138 GError *error = NULL;
140 g_assert (object == NULL);
141 g_assert (g_task_is_valid (result, object));
142 g_assert (g_async_result_get_user_data (result) == user_data);
143 g_assert (g_task_had_error (G_TASK (result)));
144 g_assert_false (g_task_get_completed (G_TASK (result)));
146 *result_out = g_task_propagate_int (G_TASK (result), &error);
147 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
148 g_error_free (error);
150 g_assert (g_task_had_error (G_TASK (result)));
152 g_main_loop_quit (loop);
156 error_return (gpointer user_data)
158 GTask *task = user_data;
160 g_task_return_new_error (task,
161 G_IO_ERROR, G_IO_ERROR_FAILED,
163 g_object_unref (task);
169 error_destroy_notify (gpointer user_data)
171 gboolean *destroyed = user_data;
181 gboolean first_task_data_destroyed = FALSE;
182 gboolean second_task_data_destroyed = FALSE;
183 gboolean notification_emitted = FALSE;
185 task = g_task_new (NULL, NULL, error_callback, &result);
186 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
187 g_signal_connect (task, "notify::completed",
188 (GCallback) completed_cb, ¬ification_emitted);
190 g_assert (first_task_data_destroyed == FALSE);
191 g_task_set_task_data (task, &first_task_data_destroyed, error_destroy_notify);
192 g_assert (first_task_data_destroyed == FALSE);
194 /* Calling g_task_set_task_data() again will destroy the first data */
195 g_task_set_task_data (task, &second_task_data_destroyed, error_destroy_notify);
196 g_assert (first_task_data_destroyed == TRUE);
197 g_assert (second_task_data_destroyed == FALSE);
199 g_idle_add (error_return, task);
200 g_main_loop_run (loop);
202 g_assert_cmpint (result, ==, -1);
203 g_assert (second_task_data_destroyed == TRUE);
204 g_assert_true (notification_emitted);
205 g_assert (task == NULL);
208 /* test_return_from_same_iteration: calling g_task_return_* from the
209 * loop iteration the task was created in defers completion until the
212 gboolean same_result = FALSE;
213 gboolean same_notification_emitted = FALSE;
216 same_callback (GObject *object,
217 GAsyncResult *result,
220 gboolean *result_out = user_data;
221 GError *error = NULL;
223 g_assert (object == NULL);
224 g_assert (g_task_is_valid (result, object));
225 g_assert (g_async_result_get_user_data (result) == user_data);
226 g_assert (!g_task_had_error (G_TASK (result)));
227 g_assert_false (g_task_get_completed (G_TASK (result)));
229 *result_out = g_task_propagate_boolean (G_TASK (result), &error);
230 g_assert_no_error (error);
232 g_assert (!g_task_had_error (G_TASK (result)));
234 g_main_loop_quit (loop);
238 same_start (gpointer user_data)
240 gpointer *weak_pointer = user_data;
243 task = g_task_new (NULL, NULL, same_callback, &same_result);
244 *weak_pointer = task;
245 g_object_add_weak_pointer (G_OBJECT (task), weak_pointer);
246 g_signal_connect (task, "notify::completed",
247 (GCallback) completed_cb, &same_notification_emitted);
249 g_task_return_boolean (task, TRUE);
250 g_object_unref (task);
252 /* same_callback should not have been invoked yet */
253 g_assert (same_result == FALSE);
254 g_assert (*weak_pointer == task);
255 g_assert_false (same_notification_emitted);
261 test_return_from_same_iteration (void)
263 gpointer weak_pointer;
265 g_idle_add (same_start, &weak_pointer);
266 g_main_loop_run (loop);
268 g_assert (same_result == TRUE);
269 g_assert (weak_pointer == NULL);
270 g_assert_true (same_notification_emitted);
273 /* test_return_from_toplevel: calling g_task_return_* from outside any
274 * main loop completes the task inside the main loop.
276 gboolean toplevel_notification_emitted = FALSE;
279 toplevel_callback (GObject *object,
280 GAsyncResult *result,
283 gboolean *result_out = user_data;
284 GError *error = NULL;
286 g_assert (object == NULL);
287 g_assert (g_task_is_valid (result, object));
288 g_assert (g_async_result_get_user_data (result) == user_data);
289 g_assert (!g_task_had_error (G_TASK (result)));
290 g_assert_false (g_task_get_completed (G_TASK (result)));
292 *result_out = g_task_propagate_boolean (G_TASK (result), &error);
293 g_assert_no_error (error);
295 g_assert (!g_task_had_error (G_TASK (result)));
297 g_main_loop_quit (loop);
301 test_return_from_toplevel (void)
304 gboolean result = FALSE;
306 task = g_task_new (NULL, NULL, toplevel_callback, &result);
307 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
308 g_signal_connect (task, "notify::completed",
309 (GCallback) completed_cb, &toplevel_notification_emitted);
311 g_task_return_boolean (task, TRUE);
312 g_object_unref (task);
314 /* toplevel_callback should not have been invoked yet */
315 g_assert (result == FALSE);
316 g_assert (task != NULL);
317 g_assert_false (toplevel_notification_emitted);
319 g_main_loop_run (loop);
321 g_assert (result == TRUE);
322 g_assert (task == NULL);
323 g_assert_true (toplevel_notification_emitted);
326 /* test_return_from_anon_thread: calling g_task_return_* from a
327 * thread with no thread-default main context will complete the
328 * task in the task's context/thread.
331 gboolean anon_thread_notification_emitted = FALSE;
332 GThread *anon_thread;
335 anon_callback (GObject *object,
336 GAsyncResult *result,
339 gssize *result_out = user_data;
340 GError *error = NULL;
342 g_assert (object == NULL);
343 g_assert (g_task_is_valid (result, object));
344 g_assert (g_async_result_get_user_data (result) == user_data);
345 g_assert (!g_task_had_error (G_TASK (result)));
346 g_assert_false (g_task_get_completed (G_TASK (result)));
348 g_assert (g_thread_self () == main_thread);
350 *result_out = g_task_propagate_int (G_TASK (result), &error);
351 g_assert_no_error (error);
353 g_assert (!g_task_had_error (G_TASK (result)));
355 g_main_loop_quit (loop);
359 anon_thread_func (gpointer user_data)
361 GTask *task = user_data;
363 g_task_return_int (task, magic);
364 g_object_unref (task);
370 anon_start (gpointer user_data)
372 GTask *task = user_data;
374 anon_thread = g_thread_new ("test_return_from_anon_thread",
375 anon_thread_func, task);
380 test_return_from_anon_thread (void)
385 task = g_task_new (NULL, NULL, anon_callback, &result);
386 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
387 g_signal_connect (task, "notify::completed",
388 (GCallback) completed_cb,
389 &anon_thread_notification_emitted);
391 g_idle_add (anon_start, task);
392 g_main_loop_run (loop);
394 g_thread_join (anon_thread);
396 g_assert_cmpint (result, ==, magic);
397 g_assert (task == NULL);
398 g_assert_true (anon_thread_notification_emitted);
401 /* test_return_from_wrong_thread: calling g_task_return_* from a
402 * thread with its own thread-default main context will complete the
403 * task in the task's context/thread.
406 gboolean wrong_thread_notification_emitted = FALSE;
407 GThread *wrong_thread;
410 wrong_callback (GObject *object,
411 GAsyncResult *result,
414 gssize *result_out = user_data;
415 GError *error = NULL;
417 g_assert (object == NULL);
418 g_assert (g_task_is_valid (result, object));
419 g_assert (g_async_result_get_user_data (result) == user_data);
420 g_assert (!g_task_had_error (G_TASK (result)));
421 g_assert_false (g_task_get_completed (G_TASK (result)));
423 g_assert (g_thread_self () == main_thread);
425 *result_out = g_task_propagate_int (G_TASK (result), &error);
426 g_assert_no_error (error);
428 g_assert (!g_task_had_error (G_TASK (result)));
430 g_main_loop_quit (loop);
434 wrong_thread_func (gpointer user_data)
436 GTask *task = user_data;
437 GMainContext *context;
439 context = g_main_context_new ();
440 g_main_context_push_thread_default (context);
442 g_assert (g_task_get_context (task) != context);
444 g_task_return_int (task, magic);
445 g_object_unref (task);
447 g_main_context_pop_thread_default (context);
448 g_main_context_unref (context);
454 wrong_start (gpointer user_data)
456 GTask *task = user_data;
458 wrong_thread = g_thread_new ("test_return_from_anon_thread",
459 wrong_thread_func, task);
464 test_return_from_wrong_thread (void)
469 task = g_task_new (NULL, NULL, wrong_callback, &result);
470 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
471 g_signal_connect (task, "notify::completed",
472 (GCallback) completed_cb,
473 &wrong_thread_notification_emitted);
475 g_idle_add (wrong_start, task);
476 g_main_loop_run (loop);
478 g_thread_join (wrong_thread);
480 g_assert_cmpint (result, ==, magic);
481 g_assert (task == NULL);
482 g_assert_true (wrong_thread_notification_emitted);
485 /* test_no_callback */
488 test_no_callback (void)
492 task = g_task_new (NULL, NULL, NULL, NULL);
493 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
495 g_task_return_boolean (task, TRUE);
496 g_object_unref (task);
498 /* Even though there’s no callback, the :completed notification has to
499 * happen in an idle handler. */
500 g_assert_nonnull (task);
501 wait_for_completed_notification (task);
502 g_assert_null (task);
505 /* test_report_error */
507 static void test_report_error (void);
508 gboolean error_notification_emitted = FALSE;
511 report_callback (GObject *object,
512 GAsyncResult *result,
515 gpointer *weak_pointer = user_data;
516 GError *error = NULL;
519 g_assert (object == NULL);
520 g_assert (g_task_is_valid (result, object));
521 g_assert (g_async_result_get_user_data (result) == user_data);
522 g_assert (g_async_result_is_tagged (result, test_report_error));
523 g_assert (g_task_get_source_tag (G_TASK (result)) == test_report_error);
524 g_assert (g_task_had_error (G_TASK (result)));
525 g_assert_false (g_task_get_completed (G_TASK (result)));
527 ret = g_task_propagate_int (G_TASK (result), &error);
528 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
529 g_assert_cmpint (ret, ==, -1);
530 g_error_free (error);
532 g_assert (g_task_had_error (G_TASK (result)));
534 *weak_pointer = result;
535 g_object_add_weak_pointer (G_OBJECT (result), weak_pointer);
536 g_signal_connect (result, "notify::completed",
537 (GCallback) completed_cb, &error_notification_emitted);
539 g_main_loop_quit (loop);
543 test_report_error (void)
545 gpointer weak_pointer = (gpointer)-1;
547 g_task_report_new_error (NULL, report_callback, &weak_pointer,
549 G_IO_ERROR, G_IO_ERROR_FAILED,
551 g_main_loop_run (loop);
553 g_assert (weak_pointer == NULL);
554 g_assert_true (error_notification_emitted);
557 /* test_priority: tasks complete in priority order */
559 static int counter = 0;
562 priority_callback (GObject *object,
563 GAsyncResult *result,
566 gssize *ret_out = user_data;
567 GError *error = NULL;
569 g_assert (object == NULL);
570 g_assert (g_task_is_valid (result, object));
571 g_assert (g_async_result_get_user_data (result) == user_data);
572 g_assert (!g_task_had_error (G_TASK (result)));
573 g_assert_false (g_task_get_completed (G_TASK (result)));
575 g_task_propagate_boolean (G_TASK (result), &error);
576 g_assert_no_error (error);
578 g_assert (!g_task_had_error (G_TASK (result)));
580 *ret_out = ++counter;
583 g_main_loop_quit (loop);
590 gssize ret1, ret2, ret3;
592 /* t2 has higher priority than either t1 or t3, so we can't
593 * accidentally pass the test just by completing the tasks in the
594 * order they were created (or in reverse order).
597 t1 = g_task_new (NULL, NULL, priority_callback, &ret1);
598 g_task_set_priority (t1, G_PRIORITY_DEFAULT);
599 g_task_return_boolean (t1, TRUE);
602 t2 = g_task_new (NULL, NULL, priority_callback, &ret2);
603 g_task_set_priority (t2, G_PRIORITY_HIGH);
604 g_task_return_boolean (t2, TRUE);
607 t3 = g_task_new (NULL, NULL, priority_callback, &ret3);
608 g_task_set_priority (t3, G_PRIORITY_LOW);
609 g_task_return_boolean (t3, TRUE);
612 g_main_loop_run (loop);
614 g_assert_cmpint (ret2, ==, 1);
615 g_assert_cmpint (ret1, ==, 2);
616 g_assert_cmpint (ret3, ==, 3);
619 /* Test that getting and setting the task name works. */
620 static void name_callback (GObject *object,
621 GAsyncResult *result,
628 char *orig = g_strdup ("some task");
631 t1 = g_task_new (NULL, NULL, name_callback, &name1);
632 (g_task_set_name) (t1, orig);
633 g_task_return_boolean (t1, TRUE);
636 g_main_loop_run (loop);
638 g_assert_cmpstr (name1, ==, orig);
645 test_name_macro_wrapper (void)
648 char *orig = g_strdup ("some task");
651 t1 = g_task_new (NULL, NULL, name_callback, &name1);
652 g_task_set_name (t1, orig);
653 g_task_return_boolean (t1, TRUE);
656 g_main_loop_run (loop);
658 g_assert_cmpstr (name1, ==, orig);
665 name_callback (GObject *object,
666 GAsyncResult *result,
669 gchar **name_out = user_data;
670 GError *local_error = NULL;
672 g_assert_null (*name_out);
673 *name_out = g_strdup (g_task_get_name (G_TASK (result)));
675 g_task_propagate_boolean (G_TASK (result), &local_error);
676 g_assert_no_error (local_error);
678 g_main_loop_quit (loop);
681 static void static_name_callback (GObject *object,
682 GAsyncResult *result,
686 test_static_name (void)
689 char *orig = "some task";
692 t1 = g_task_new (NULL, NULL, static_name_callback, &name1);
693 g_task_set_static_name (t1, orig);
694 g_task_return_boolean (t1, TRUE);
697 g_main_loop_run (loop);
699 g_assert_true (name1 == orig);
703 static_name_callback (GObject *object,
704 GAsyncResult *result,
707 const char **name_out = user_data;
708 GError *local_error = NULL;
710 g_assert_null (*name_out);
711 *name_out = g_task_get_name (G_TASK (result));
713 g_task_propagate_boolean (G_TASK (result), &local_error);
714 g_assert_no_error (local_error);
716 g_main_loop_quit (loop);
719 /* test_asynchronous_cancellation: cancelled tasks are returned
720 * asynchronously, i.e. not from inside the GCancellable::cancelled
723 * The test is set up further below in test_asynchronous_cancellation.
726 /* asynchronous_cancellation_callback represents the callback that the
727 * caller of a typical asynchronous API would have passed. See
728 * test_asynchronous_cancellation.
731 asynchronous_cancellation_callback (GObject *object,
732 GAsyncResult *result,
735 GError *error = NULL;
738 g_assert_null (object);
739 g_assert_true (g_task_is_valid (result, object));
740 g_assert_true (g_async_result_get_user_data (result) == user_data);
741 g_assert_true (g_task_had_error (G_TASK (result)));
742 g_assert_false (g_task_get_completed (G_TASK (result)));
744 run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (G_TASK (result)));
745 g_assert_cmpuint (run_task_id, ==, 0);
747 g_task_propagate_boolean (G_TASK (result), &error);
748 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
749 g_clear_error (&error);
751 g_assert_true (g_task_had_error (G_TASK (result)));
753 g_main_loop_quit (loop);
756 /* asynchronous_cancellation_cancel_task represents a user cancelling
757 * the ongoing operation. To make it somewhat realistic it is delayed
758 * by 50ms via a timeout GSource. See test_asynchronous_cancellation.
761 asynchronous_cancellation_cancel_task (gpointer user_data)
763 GCancellable *cancellable;
764 GTask *task = G_TASK (user_data);
766 cancellable = g_task_get_cancellable (task);
767 g_assert_true (G_IS_CANCELLABLE (cancellable));
769 g_cancellable_cancel (cancellable);
770 g_assert_false (g_task_get_completed (task));
772 return G_SOURCE_REMOVE;
775 /* asynchronous_cancellation_cancelled is the GCancellable::cancelled
776 * handler that's used by the asynchronous implementation for
780 asynchronous_cancellation_cancelled (GCancellable *cancellable,
783 GTask *task = G_TASK (user_data);
786 g_assert_true (cancellable == g_task_get_cancellable (task));
788 run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (task));
789 g_assert_cmpuint (run_task_id, !=, 0);
791 g_source_remove (run_task_id);
792 g_task_set_task_data (task, GUINT_TO_POINTER (0), NULL);
794 g_task_return_boolean (task, FALSE);
795 g_assert_false (g_task_get_completed (task));
798 /* asynchronous_cancellation_run_task represents the actual
799 * asynchronous work being done in an idle GSource as was mentioned
800 * above. This is effectively meant to be an infinite loop so that
801 * the only way to break out of it is via cancellation.
804 asynchronous_cancellation_run_task (gpointer user_data)
806 GCancellable *cancellable;
807 GTask *task = G_TASK (user_data);
809 cancellable = g_task_get_cancellable (task);
810 g_assert_true (G_IS_CANCELLABLE (cancellable));
811 g_assert_false (g_cancellable_is_cancelled (cancellable));
813 return G_SOURCE_CONTINUE;
816 /* Test that cancellation is always asynchronous. The completion callback for
817 * a #GTask must not be called from inside the cancellation handler.
819 * The body of the loop inside test_asynchronous_cancellation
820 * represents what would have been a typical asynchronous API call,
821 * and its implementation. They are fused together without an API
822 * boundary. The actual work done by this asynchronous API is
823 * represented by an idle GSource.
826 test_asynchronous_cancellation (void)
830 g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1608");
832 /* Run a few times to shake out any timing issues between the
833 * cancellation and task sources.
835 for (i = 0; i < 5; i++)
837 GCancellable *cancellable;
839 gboolean notification_emitted = FALSE;
842 cancellable = g_cancellable_new ();
844 task = g_task_new (NULL, cancellable, asynchronous_cancellation_callback, NULL);
845 g_cancellable_connect (cancellable, (GCallback) asynchronous_cancellation_cancelled, task, NULL);
846 g_signal_connect (task, "notify::completed", (GCallback) completed_cb, ¬ification_emitted);
848 run_task_id = g_idle_add (asynchronous_cancellation_run_task, task);
849 g_source_set_name_by_id (run_task_id, "[test_asynchronous_cancellation] run_task");
850 g_task_set_task_data (task, GUINT_TO_POINTER (run_task_id), NULL);
852 g_timeout_add (50, asynchronous_cancellation_cancel_task, task);
854 g_main_loop_run (loop);
856 g_assert_true (g_task_get_completed (task));
857 g_assert_true (notification_emitted);
859 g_object_unref (cancellable);
860 g_object_unref (task);
864 /* test_check_cancellable: cancellation overrides return value */
867 CANCEL_BEFORE = (1 << 1),
868 CANCEL_AFTER = (1 << 2),
869 CHECK_CANCELLABLE = (1 << 3)
871 #define NUM_CANCEL_TESTS (CANCEL_BEFORE | CANCEL_AFTER | CHECK_CANCELLABLE)
874 cancel_callback (GObject *object,
875 GAsyncResult *result,
878 int state = GPOINTER_TO_INT (user_data);
880 GCancellable *cancellable;
881 GError *error = NULL;
883 g_assert (object == NULL);
884 g_assert (g_task_is_valid (result, object));
885 g_assert (g_async_result_get_user_data (result) == user_data);
887 task = G_TASK (result);
888 cancellable = g_task_get_cancellable (task);
889 g_assert (G_IS_CANCELLABLE (cancellable));
891 if (state & (CANCEL_BEFORE | CANCEL_AFTER))
892 g_assert (g_cancellable_is_cancelled (cancellable));
894 g_assert (!g_cancellable_is_cancelled (cancellable));
896 if (state & CHECK_CANCELLABLE)
897 g_assert (g_task_get_check_cancellable (task));
899 g_assert (!g_task_get_check_cancellable (task));
901 if (g_task_propagate_boolean (task, &error))
903 g_assert (!g_cancellable_is_cancelled (cancellable) ||
904 !g_task_get_check_cancellable (task));
908 g_assert (g_cancellable_is_cancelled (cancellable) &&
909 g_task_get_check_cancellable (task));
910 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
911 g_error_free (error);
914 g_main_loop_quit (loop);
918 test_check_cancellable (void)
921 GCancellable *cancellable;
924 cancellable = g_cancellable_new ();
926 for (state = 0; state <= NUM_CANCEL_TESTS; state++)
928 task = g_task_new (NULL, cancellable, cancel_callback,
929 GINT_TO_POINTER (state));
930 g_task_set_check_cancellable (task, (state & CHECK_CANCELLABLE) != 0);
932 if (state & CANCEL_BEFORE)
933 g_cancellable_cancel (cancellable);
934 g_task_return_boolean (task, TRUE);
935 if (state & CANCEL_AFTER)
936 g_cancellable_cancel (cancellable);
938 g_main_loop_run (loop);
939 g_object_unref (task);
940 g_cancellable_reset (cancellable);
943 g_object_unref (cancellable);
946 /* test_return_if_cancelled */
949 return_if_cancelled_callback (GObject *object,
950 GAsyncResult *result,
953 GError *error = NULL;
955 g_assert (object == NULL);
956 g_assert (g_task_is_valid (result, object));
957 g_assert (g_async_result_get_user_data (result) == user_data);
958 g_assert (g_task_had_error (G_TASK (result)));
959 g_assert_false (g_task_get_completed (G_TASK (result)));
961 g_task_propagate_boolean (G_TASK (result), &error);
962 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
963 g_clear_error (&error);
965 g_assert (g_task_had_error (G_TASK (result)));
967 g_main_loop_quit (loop);
971 test_return_if_cancelled (void)
974 GCancellable *cancellable;
976 gboolean notification_emitted = FALSE;
978 cancellable = g_cancellable_new ();
980 task = g_task_new (NULL, cancellable, return_if_cancelled_callback, NULL);
981 g_signal_connect (task, "notify::completed",
982 (GCallback) completed_cb, ¬ification_emitted);
984 g_cancellable_cancel (cancellable);
985 cancelled = g_task_return_error_if_cancelled (task);
986 g_assert (cancelled);
987 g_assert_false (notification_emitted);
988 g_main_loop_run (loop);
989 g_object_unref (task);
990 g_assert_true (notification_emitted);
991 g_cancellable_reset (cancellable);
993 notification_emitted = FALSE;
995 task = g_task_new (NULL, cancellable, return_if_cancelled_callback, NULL);
996 g_signal_connect (task, "notify::completed",
997 (GCallback) completed_cb, ¬ification_emitted);
999 g_task_set_check_cancellable (task, FALSE);
1000 g_cancellable_cancel (cancellable);
1001 cancelled = g_task_return_error_if_cancelled (task);
1002 g_assert (cancelled);
1003 g_assert_false (notification_emitted);
1004 g_main_loop_run (loop);
1005 g_object_unref (task);
1006 g_assert_true (notification_emitted);
1007 g_object_unref (cancellable);
1010 /* test_run_in_thread */
1012 static GMutex run_in_thread_mutex;
1013 static GCond run_in_thread_cond;
1016 task_weak_notify (gpointer user_data,
1019 gboolean *weak_notify_ran = user_data;
1021 g_mutex_lock (&run_in_thread_mutex);
1022 g_atomic_int_set (weak_notify_ran, TRUE);
1023 g_cond_signal (&run_in_thread_cond);
1024 g_mutex_unlock (&run_in_thread_mutex);
1028 run_in_thread_callback (GObject *object,
1029 GAsyncResult *result,
1032 gboolean *done = user_data;
1033 GError *error = NULL;
1036 g_assert (g_thread_self () == main_thread);
1038 g_assert (object == NULL);
1039 g_assert (g_task_is_valid (result, object));
1040 g_assert (g_async_result_get_user_data (result) == user_data);
1041 g_assert (!g_task_had_error (G_TASK (result)));
1042 g_assert_false (g_task_get_completed (G_TASK (result)));
1043 g_assert_cmpstr (g_task_get_name (G_TASK (result)), ==, "test_run_in_thread name");
1045 ret = g_task_propagate_int (G_TASK (result), &error);
1046 g_assert_no_error (error);
1047 g_assert_cmpint (ret, ==, magic);
1049 g_assert (!g_task_had_error (G_TASK (result)));
1052 g_main_loop_quit (loop);
1056 run_in_thread_thread (GTask *task,
1057 gpointer source_object,
1059 GCancellable *cancellable)
1061 gboolean *thread_ran = task_data;
1063 g_assert (source_object == g_task_get_source_object (task));
1064 g_assert (task_data == g_task_get_task_data (task));
1065 g_assert (cancellable == g_task_get_cancellable (task));
1066 g_assert_false (g_task_get_completed (task));
1067 g_assert_cmpstr (g_task_get_name (task), ==, "test_run_in_thread name");
1069 g_assert (g_thread_self () != main_thread);
1071 g_mutex_lock (&run_in_thread_mutex);
1072 g_atomic_int_set (thread_ran, TRUE);
1073 g_cond_signal (&run_in_thread_cond);
1074 g_mutex_unlock (&run_in_thread_mutex);
1076 g_task_return_int (task, magic);
1080 test_run_in_thread (void)
1083 gboolean thread_ran = FALSE; /* (atomic) */
1084 gboolean weak_notify_ran = FALSE; /* (atomic) */
1085 gboolean notification_emitted = FALSE;
1086 gboolean done = FALSE;
1088 task = g_task_new (NULL, NULL, run_in_thread_callback, &done);
1089 g_task_set_name (task, "test_run_in_thread name");
1090 g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran);
1091 g_signal_connect (task, "notify::completed",
1092 (GCallback) completed_cb, ¬ification_emitted);
1094 g_task_set_task_data (task, (gpointer)&thread_ran, NULL);
1095 g_task_run_in_thread (task, run_in_thread_thread);
1097 g_mutex_lock (&run_in_thread_mutex);
1098 while (!g_atomic_int_get (&thread_ran))
1099 g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
1100 g_mutex_unlock (&run_in_thread_mutex);
1102 g_assert (done == FALSE);
1103 g_assert_false (g_atomic_int_get (&weak_notify_ran));
1105 g_main_loop_run (loop);
1107 g_assert (done == TRUE);
1108 g_assert_true (notification_emitted);
1110 g_assert_cmpstr (g_task_get_name (task), ==, "test_run_in_thread name");
1112 g_object_unref (task);
1114 g_mutex_lock (&run_in_thread_mutex);
1115 while (!g_atomic_int_get (&weak_notify_ran))
1116 g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
1117 g_mutex_unlock (&run_in_thread_mutex);
1120 /* test_run_in_thread_sync */
1123 run_in_thread_sync_callback (GObject *object,
1124 GAsyncResult *result,
1127 /* g_task_run_in_thread_sync() does not invoke the task's callback */
1128 g_assert_not_reached ();
1132 run_in_thread_sync_thread (GTask *task,
1133 gpointer source_object,
1135 GCancellable *cancellable)
1137 gboolean *thread_ran = task_data;
1139 g_assert (source_object == g_task_get_source_object (task));
1140 g_assert (task_data == g_task_get_task_data (task));
1141 g_assert (cancellable == g_task_get_cancellable (task));
1142 g_assert_false (g_task_get_completed (task));
1144 g_assert (g_thread_self () != main_thread);
1146 g_atomic_int_set (thread_ran, TRUE);
1147 g_task_return_int (task, magic);
1151 test_run_in_thread_sync (void)
1154 gboolean thread_ran = FALSE;
1156 gboolean notification_emitted = FALSE;
1157 GError *error = NULL;
1159 task = g_task_new (NULL, NULL, run_in_thread_sync_callback, NULL);
1160 g_signal_connect (task, "notify::completed",
1161 (GCallback) completed_cb,
1162 ¬ification_emitted);
1164 g_task_set_task_data (task, &thread_ran, NULL);
1165 g_task_run_in_thread_sync (task, run_in_thread_sync_thread);
1167 g_assert_true (g_atomic_int_get (&thread_ran));
1168 g_assert (task != NULL);
1169 g_assert (!g_task_had_error (task));
1170 g_assert_true (g_task_get_completed (task));
1171 g_assert_true (notification_emitted);
1173 ret = g_task_propagate_int (task, &error);
1174 g_assert_no_error (error);
1175 g_assert_cmpint (ret, ==, magic);
1177 g_assert (!g_task_had_error (task));
1179 g_object_unref (task);
1182 /* test_run_in_thread_priority */
1184 static GMutex fake_task_mutex, last_fake_task_mutex;
1185 static gint sequence_number = 0;
1188 quit_main_loop_callback (GObject *object,
1189 GAsyncResult *result,
1192 GError *error = NULL;
1195 g_assert (g_thread_self () == main_thread);
1197 g_assert (object == NULL);
1198 g_assert (g_task_is_valid (result, object));
1199 g_assert (g_async_result_get_user_data (result) == user_data);
1200 g_assert (!g_task_had_error (G_TASK (result)));
1201 g_assert_false (g_task_get_completed (G_TASK (result)));
1203 ret = g_task_propagate_boolean (G_TASK (result), &error);
1204 g_assert_no_error (error);
1205 g_assert_cmpint (ret, ==, TRUE);
1207 g_assert (!g_task_had_error (G_TASK (result)));
1209 g_main_loop_quit (loop);
1213 set_sequence_number_thread (GTask *task,
1214 gpointer source_object,
1216 GCancellable *cancellable)
1218 gint *seq_no_p = task_data;
1220 *seq_no_p = ++sequence_number;
1221 g_task_return_boolean (task, TRUE);
1225 fake_task_thread (GTask *task,
1226 gpointer source_object,
1228 GCancellable *cancellable)
1230 GMutex *mutex = task_data;
1232 g_mutex_lock (mutex);
1233 g_mutex_unlock (mutex);
1234 g_task_return_boolean (task, TRUE);
1237 #define G_TASK_THREAD_POOL_SIZE 10
1238 static int fake_tasks_running;
1241 fake_task_callback (GObject *source,
1242 GAsyncResult *result,
1245 if (--fake_tasks_running == 0)
1246 g_main_loop_quit (loop);
1250 clog_up_thread_pool (void)
1255 g_thread_pool_stop_unused_threads ();
1257 g_mutex_lock (&fake_task_mutex);
1258 for (i = 0; i < G_TASK_THREAD_POOL_SIZE - 1; i++)
1260 task = g_task_new (NULL, NULL, fake_task_callback, NULL);
1261 g_task_set_task_data (task, &fake_task_mutex, NULL);
1262 g_assert_cmpint (g_task_get_priority (task), ==, G_PRIORITY_DEFAULT);
1263 g_task_set_priority (task, G_PRIORITY_HIGH * 2);
1264 g_assert_cmpint (g_task_get_priority (task), ==, G_PRIORITY_HIGH * 2);
1265 g_task_run_in_thread (task, fake_task_thread);
1266 g_object_unref (task);
1267 fake_tasks_running++;
1270 g_mutex_lock (&last_fake_task_mutex);
1271 task = g_task_new (NULL, NULL, NULL, NULL);
1272 g_task_set_task_data (task, &last_fake_task_mutex, NULL);
1273 g_task_set_priority (task, G_PRIORITY_HIGH * 2);
1274 g_task_run_in_thread (task, fake_task_thread);
1275 g_object_unref (task);
1279 unclog_thread_pool (void)
1281 g_mutex_unlock (&fake_task_mutex);
1282 g_main_loop_run (loop);
1286 test_run_in_thread_priority (void)
1289 GCancellable *cancellable;
1290 int seq_a, seq_b, seq_c, seq_d;
1292 clog_up_thread_pool ();
1294 /* Queue three more tasks that we'll arrange to have run serially */
1295 task = g_task_new (NULL, NULL, NULL, NULL);
1296 g_task_set_task_data (task, &seq_a, NULL);
1297 g_task_run_in_thread (task, set_sequence_number_thread);
1298 g_object_unref (task);
1300 task = g_task_new (NULL, NULL, quit_main_loop_callback, NULL);
1301 g_task_set_task_data (task, &seq_b, NULL);
1302 g_task_set_priority (task, G_PRIORITY_LOW);
1303 g_task_run_in_thread (task, set_sequence_number_thread);
1304 g_object_unref (task);
1306 task = g_task_new (NULL, NULL, NULL, NULL);
1307 g_task_set_task_data (task, &seq_c, NULL);
1308 g_task_set_priority (task, G_PRIORITY_HIGH);
1309 g_task_run_in_thread (task, set_sequence_number_thread);
1310 g_object_unref (task);
1312 cancellable = g_cancellable_new ();
1313 task = g_task_new (NULL, cancellable, NULL, NULL);
1314 g_task_set_task_data (task, &seq_d, NULL);
1315 g_task_run_in_thread (task, set_sequence_number_thread);
1316 g_cancellable_cancel (cancellable);
1317 g_object_unref (cancellable);
1318 g_object_unref (task);
1320 /* Let the last fake task complete; the four other tasks will then
1321 * complete serially, in the order D, C, A, B, and B will quit the
1324 g_mutex_unlock (&last_fake_task_mutex);
1325 g_main_loop_run (loop);
1327 g_assert_cmpint (seq_d, ==, 1);
1328 g_assert_cmpint (seq_c, ==, 2);
1329 g_assert_cmpint (seq_a, ==, 3);
1330 g_assert_cmpint (seq_b, ==, 4);
1332 unclog_thread_pool ();
1335 /* test_run_in_thread_nested: task threads that block waiting on
1336 * other task threads will not cause the thread pool to starve.
1340 run_nested_task_thread (GTask *task,
1341 gpointer source_object,
1343 GCancellable *cancellable)
1346 int *nested_tasks_left = task_data;
1348 if ((*nested_tasks_left)--)
1350 nested = g_task_new (NULL, NULL, NULL, NULL);
1351 g_task_set_task_data (nested, nested_tasks_left, NULL);
1352 g_task_run_in_thread_sync (nested, run_nested_task_thread);
1353 g_object_unref (nested);
1356 g_task_return_boolean (task, TRUE);
1360 test_run_in_thread_nested (void)
1363 int nested_tasks_left = 2;
1365 clog_up_thread_pool ();
1367 task = g_task_new (NULL, NULL, quit_main_loop_callback, NULL);
1368 g_task_set_task_data (task, &nested_tasks_left, NULL);
1369 g_task_run_in_thread (task, run_nested_task_thread);
1370 g_object_unref (task);
1372 g_mutex_unlock (&last_fake_task_mutex);
1373 g_main_loop_run (loop);
1375 unclog_thread_pool ();
1378 /* test_run_in_thread_overflow: if you queue lots and lots and lots of
1379 * tasks, they won't all run at once.
1381 static GMutex overflow_mutex;
1382 static guint overflow_completed;
1385 run_overflow_task_thread (GTask *task,
1386 gpointer source_object,
1388 GCancellable *cancellable)
1390 gchar *result = task_data;
1392 if (g_task_return_error_if_cancelled (task))
1398 /* Block until the main thread is ready. */
1399 g_mutex_lock (&overflow_mutex);
1400 g_mutex_unlock (&overflow_mutex);
1404 g_task_return_boolean (task, TRUE);
1407 g_atomic_int_inc (&overflow_completed);
1410 #define NUM_OVERFLOW_TASKS 1024
1413 test_run_in_thread_overflow (void)
1415 GCancellable *cancellable;
1417 gchar buf[NUM_OVERFLOW_TASKS + 1];
1420 /* Queue way too many tasks and then sleep for a bit. The first 10
1421 * tasks will be dispatched to threads and will then block on
1422 * overflow_mutex, so more threads will be created while this thread
1423 * is sleeping. Then we cancel the cancellable, unlock the mutex,
1424 * wait for all of the tasks to complete, and make sure that we got
1425 * the behavior we expected.
1428 memset (buf, 0, sizeof (buf));
1429 cancellable = g_cancellable_new ();
1431 g_mutex_lock (&overflow_mutex);
1433 for (i = 0; i < NUM_OVERFLOW_TASKS; i++)
1435 task = g_task_new (NULL, cancellable, NULL, NULL);
1436 g_task_set_task_data (task, buf + i, NULL);
1437 g_task_run_in_thread (task, run_overflow_task_thread);
1438 g_object_unref (task);
1442 g_usleep (5000000); /* 5 s */
1444 g_usleep (500000); /* 0.5 s */
1445 g_cancellable_cancel (cancellable);
1446 g_object_unref (cancellable);
1448 g_mutex_unlock (&overflow_mutex);
1450 /* Wait for all tasks to complete. */
1451 while (g_atomic_int_get (&overflow_completed) != NUM_OVERFLOW_TASKS)
1454 g_assert_cmpint (strlen (buf), ==, NUM_OVERFLOW_TASKS);
1456 i = strspn (buf, ".");
1457 /* Given the sleep times above, i should be 14 for normal, 40 for
1458 * slow. But if the machine is too slow/busy then the scheduling
1459 * might get messed up and we'll get more or fewer threads than
1460 * expected. But there are limits to how messed up it could
1461 * plausibly get (and we hope that if gtask is actually broken then
1462 * it will exceed those limits).
1464 g_assert_cmpint (i, >=, 10);
1466 g_assert_cmpint (i, <, 50);
1468 g_assert_cmpint (i, <, 20);
1470 g_assert_cmpint (i + strspn (buf + i, "X"), ==, NUM_OVERFLOW_TASKS);
1473 /* test_return_on_cancel */
1475 GMutex roc_init_mutex, roc_finish_mutex;
1476 GCond roc_init_cond, roc_finish_cond;
1486 return_on_cancel_callback (GObject *object,
1487 GAsyncResult *result,
1490 gboolean *callback_ran = user_data;
1491 GError *error = NULL;
1494 g_assert (g_thread_self () == main_thread);
1496 g_assert (object == NULL);
1497 g_assert (g_task_is_valid (result, object));
1498 g_assert (g_async_result_get_user_data (result) == user_data);
1499 g_assert (g_task_had_error (G_TASK (result)));
1500 g_assert_false (g_task_get_completed (G_TASK (result)));
1502 ret = g_task_propagate_int (G_TASK (result), &error);
1503 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1504 g_clear_error (&error);
1505 g_assert_cmpint (ret, ==, -1);
1507 g_assert (g_task_had_error (G_TASK (result)));
1509 *callback_ran = TRUE;
1510 g_main_loop_quit (loop);
1514 return_on_cancel_thread (GTask *task,
1515 gpointer source_object,
1517 GCancellable *cancellable)
1519 ThreadState *state = task_data;
1521 g_assert (source_object == g_task_get_source_object (task));
1522 g_assert (task_data == g_task_get_task_data (task));
1523 g_assert (cancellable == g_task_get_cancellable (task));
1525 g_assert (g_thread_self () != main_thread);
1527 g_mutex_lock (&roc_init_mutex);
1528 *state = THREAD_RUNNING;
1529 g_cond_signal (&roc_init_cond);
1530 g_mutex_unlock (&roc_init_mutex);
1532 g_mutex_lock (&roc_finish_mutex);
1534 if (!g_task_get_return_on_cancel (task) ||
1535 g_task_set_return_on_cancel (task, FALSE))
1537 *state = THREAD_COMPLETED;
1538 g_task_return_int (task, magic);
1541 *state = THREAD_CANCELLED;
1543 g_cond_signal (&roc_finish_cond);
1544 g_mutex_unlock (&roc_finish_mutex);
1548 test_return_on_cancel (void)
1551 GCancellable *cancellable;
1552 ThreadState thread_state; /* (atomic) */
1553 gboolean weak_notify_ran = FALSE; /* (atomic) */
1554 gboolean callback_ran;
1555 gboolean notification_emitted = FALSE;
1557 cancellable = g_cancellable_new ();
1559 /* If return-on-cancel is FALSE (default), the task does not return
1562 callback_ran = FALSE;
1563 g_atomic_int_set (&thread_state, THREAD_STARTING);
1564 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1565 g_signal_connect (task, "notify::completed",
1566 (GCallback) completed_cb, ¬ification_emitted);
1568 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1569 g_mutex_lock (&roc_init_mutex);
1570 g_mutex_lock (&roc_finish_mutex);
1571 g_task_run_in_thread (task, return_on_cancel_thread);
1572 g_object_unref (task);
1574 while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
1575 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1576 g_mutex_unlock (&roc_init_mutex);
1578 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
1579 g_assert (callback_ran == FALSE);
1581 g_cancellable_cancel (cancellable);
1582 g_mutex_unlock (&roc_finish_mutex);
1583 g_main_loop_run (loop);
1585 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED);
1586 g_assert (callback_ran == TRUE);
1587 g_assert_true (notification_emitted);
1589 g_cancellable_reset (cancellable);
1591 /* If return-on-cancel is TRUE, it does return early */
1592 callback_ran = FALSE;
1593 notification_emitted = FALSE;
1594 g_atomic_int_set (&thread_state, THREAD_STARTING);
1595 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1596 g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran);
1597 g_signal_connect (task, "notify::completed",
1598 (GCallback) completed_cb, ¬ification_emitted);
1599 g_task_set_return_on_cancel (task, TRUE);
1601 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1602 g_mutex_lock (&roc_init_mutex);
1603 g_mutex_lock (&roc_finish_mutex);
1604 g_task_run_in_thread (task, return_on_cancel_thread);
1605 g_object_unref (task);
1607 while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
1608 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1609 g_mutex_unlock (&roc_init_mutex);
1611 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
1612 g_assert (callback_ran == FALSE);
1614 g_cancellable_cancel (cancellable);
1615 g_main_loop_run (loop);
1616 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
1617 g_assert (callback_ran == TRUE);
1619 g_assert_false (g_atomic_int_get (&weak_notify_ran));
1621 while (g_atomic_int_get (&thread_state) == THREAD_RUNNING)
1622 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1623 g_mutex_unlock (&roc_finish_mutex);
1625 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED);
1626 g_mutex_lock (&run_in_thread_mutex);
1627 while (!g_atomic_int_get (&weak_notify_ran))
1628 g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
1629 g_mutex_unlock (&run_in_thread_mutex);
1631 g_assert_true (notification_emitted);
1632 g_cancellable_reset (cancellable);
1634 /* If the task is already cancelled before it starts, it returns
1635 * immediately, but the thread func still runs.
1637 callback_ran = FALSE;
1638 notification_emitted = FALSE;
1639 g_atomic_int_set (&thread_state, THREAD_STARTING);
1640 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1641 g_signal_connect (task, "notify::completed",
1642 (GCallback) completed_cb, ¬ification_emitted);
1643 g_task_set_return_on_cancel (task, TRUE);
1645 g_cancellable_cancel (cancellable);
1647 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1648 g_mutex_lock (&roc_init_mutex);
1649 g_mutex_lock (&roc_finish_mutex);
1650 g_task_run_in_thread (task, return_on_cancel_thread);
1651 g_object_unref (task);
1653 g_main_loop_run (loop);
1654 g_assert (callback_ran == TRUE);
1656 while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
1657 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1658 g_mutex_unlock (&roc_init_mutex);
1660 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
1662 while (g_atomic_int_get (&thread_state) == THREAD_RUNNING)
1663 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1664 g_mutex_unlock (&roc_finish_mutex);
1666 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED);
1667 g_assert_true (notification_emitted);
1669 g_object_unref (cancellable);
1672 /* test_return_on_cancel_sync */
1675 cancel_sync_runner_thread (gpointer task)
1677 g_task_run_in_thread_sync (task, return_on_cancel_thread);
1682 test_return_on_cancel_sync (void)
1685 GCancellable *cancellable;
1686 ThreadState thread_state; /* (atomic) */
1687 GThread *runner_thread;
1689 GError *error = NULL;
1691 cancellable = g_cancellable_new ();
1693 /* If return-on-cancel is FALSE, the task does not return early.
1695 g_atomic_int_set (&thread_state, THREAD_STARTING);
1696 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
1698 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1699 g_mutex_lock (&roc_init_mutex);
1700 g_mutex_lock (&roc_finish_mutex);
1701 runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
1702 cancel_sync_runner_thread, task);
1704 while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
1705 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1706 g_mutex_unlock (&roc_init_mutex);
1708 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
1710 g_cancellable_cancel (cancellable);
1711 g_mutex_unlock (&roc_finish_mutex);
1712 g_thread_join (runner_thread);
1713 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED);
1715 ret = g_task_propagate_int (task, &error);
1716 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1717 g_clear_error (&error);
1718 g_assert_cmpint (ret, ==, -1);
1720 g_object_unref (task);
1722 g_cancellable_reset (cancellable);
1724 /* If return-on-cancel is TRUE, it does return early */
1725 g_atomic_int_set (&thread_state, THREAD_STARTING);
1726 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
1727 g_task_set_return_on_cancel (task, TRUE);
1729 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1730 g_mutex_lock (&roc_init_mutex);
1731 g_mutex_lock (&roc_finish_mutex);
1732 runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
1733 cancel_sync_runner_thread, task);
1735 while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
1736 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1737 g_mutex_unlock (&roc_init_mutex);
1739 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
1741 g_cancellable_cancel (cancellable);
1742 g_thread_join (runner_thread);
1743 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
1745 ret = g_task_propagate_int (task, &error);
1746 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1747 g_clear_error (&error);
1748 g_assert_cmpint (ret, ==, -1);
1750 g_object_unref (task);
1752 while (g_atomic_int_get (&thread_state) == THREAD_RUNNING)
1753 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1754 g_mutex_unlock (&roc_finish_mutex);
1756 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED);
1758 g_cancellable_reset (cancellable);
1760 /* If the task is already cancelled before it starts, it returns
1761 * immediately, but the thread func still runs.
1763 g_atomic_int_set (&thread_state, THREAD_STARTING);
1764 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
1765 g_task_set_return_on_cancel (task, TRUE);
1767 g_cancellable_cancel (cancellable);
1769 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1770 g_mutex_lock (&roc_init_mutex);
1771 g_mutex_lock (&roc_finish_mutex);
1772 runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
1773 cancel_sync_runner_thread, task);
1775 g_thread_join (runner_thread);
1776 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_STARTING);
1778 ret = g_task_propagate_int (task, &error);
1779 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1780 g_clear_error (&error);
1781 g_assert_cmpint (ret, ==, -1);
1783 g_object_unref (task);
1785 while (g_atomic_int_get (&thread_state) == THREAD_STARTING)
1786 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1787 g_mutex_unlock (&roc_init_mutex);
1789 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING);
1791 while (g_atomic_int_get (&thread_state) == THREAD_RUNNING)
1792 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1793 g_mutex_unlock (&roc_finish_mutex);
1795 g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED);
1797 g_object_unref (cancellable);
1800 /* test_return_on_cancel_atomic: turning return-on-cancel on/off is
1804 GMutex roca_mutex_1, roca_mutex_2;
1805 GCond roca_cond_1, roca_cond_2;
1808 return_on_cancel_atomic_callback (GObject *object,
1809 GAsyncResult *result,
1812 gboolean *callback_ran = user_data;
1813 GError *error = NULL;
1816 g_assert (g_thread_self () == main_thread);
1818 g_assert (object == NULL);
1819 g_assert (g_task_is_valid (result, object));
1820 g_assert (g_async_result_get_user_data (result) == user_data);
1821 g_assert (g_task_had_error (G_TASK (result)));
1822 g_assert_false (g_task_get_completed (G_TASK (result)));
1824 ret = g_task_propagate_int (G_TASK (result), &error);
1825 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1826 g_clear_error (&error);
1827 g_assert_cmpint (ret, ==, -1);
1829 g_assert (g_task_had_error (G_TASK (result)));
1831 *callback_ran = TRUE;
1832 g_main_loop_quit (loop);
1836 return_on_cancel_atomic_thread (GTask *task,
1837 gpointer source_object,
1839 GCancellable *cancellable)
1841 gint *state = task_data; /* (atomic) */
1843 g_assert (source_object == g_task_get_source_object (task));
1844 g_assert (task_data == g_task_get_task_data (task));
1845 g_assert (cancellable == g_task_get_cancellable (task));
1846 g_assert_false (g_task_get_completed (task));
1848 g_assert (g_thread_self () != main_thread);
1849 g_assert_cmpint (g_atomic_int_get (state), ==, 0);
1851 g_mutex_lock (&roca_mutex_1);
1852 g_atomic_int_set (state, 1);
1853 g_cond_signal (&roca_cond_1);
1854 g_mutex_unlock (&roca_mutex_1);
1856 g_mutex_lock (&roca_mutex_2);
1857 if (g_task_set_return_on_cancel (task, FALSE))
1858 g_atomic_int_set (state, 2);
1860 g_atomic_int_set (state, 3);
1861 g_cond_signal (&roca_cond_2);
1862 g_mutex_unlock (&roca_mutex_2);
1864 g_mutex_lock (&roca_mutex_1);
1865 if (g_task_set_return_on_cancel (task, TRUE))
1866 g_atomic_int_set (state, 4);
1868 g_atomic_int_set (state, 5);
1869 g_cond_signal (&roca_cond_1);
1870 g_mutex_unlock (&roca_mutex_1);
1872 g_mutex_lock (&roca_mutex_2);
1873 if (g_task_set_return_on_cancel (task, TRUE))
1874 g_atomic_int_set (state, 6);
1876 g_atomic_int_set (state, 7);
1877 g_cond_signal (&roca_cond_2);
1878 g_mutex_unlock (&roca_mutex_2);
1880 g_task_return_int (task, magic);
1884 test_return_on_cancel_atomic (void)
1887 GCancellable *cancellable;
1888 gint state; /* (atomic) */
1889 gboolean notification_emitted = FALSE;
1890 gboolean callback_ran;
1892 cancellable = g_cancellable_new ();
1893 g_mutex_lock (&roca_mutex_1);
1894 g_mutex_lock (&roca_mutex_2);
1896 /* If we don't cancel it, each set_return_on_cancel() call will succeed */
1897 g_atomic_int_set (&state, 0);
1898 callback_ran = FALSE;
1899 task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran);
1900 g_task_set_return_on_cancel (task, TRUE);
1901 g_signal_connect (task, "notify::completed",
1902 (GCallback) completed_cb, ¬ification_emitted);
1904 g_task_set_task_data (task, (gpointer)&state, NULL);
1905 g_task_run_in_thread (task, return_on_cancel_atomic_thread);
1906 g_object_unref (task);
1908 g_assert_cmpint (g_atomic_int_get (&state), ==, 0);
1910 while (g_atomic_int_get (&state) == 0)
1911 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1912 g_assert_cmpint (g_atomic_int_get (&state), ==, 1);
1914 while (g_atomic_int_get (&state) == 1)
1915 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1916 g_assert_cmpint (g_atomic_int_get (&state), ==, 2);
1918 while (g_atomic_int_get (&state) == 2)
1919 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1920 g_assert_cmpint (g_atomic_int_get (&state), ==, 4);
1922 while (g_atomic_int_get (&state) == 4)
1923 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1924 g_assert_cmpint (g_atomic_int_get (&state), ==, 6);
1926 /* callback assumes there'll be a cancelled error */
1927 g_cancellable_cancel (cancellable);
1929 g_assert (callback_ran == FALSE);
1930 g_main_loop_run (loop);
1931 g_assert (callback_ran == TRUE);
1932 g_assert_true (notification_emitted);
1934 g_cancellable_reset (cancellable);
1937 /* If we cancel while it's temporarily not return-on-cancel, the
1938 * task won't complete right away, and further
1939 * g_task_set_return_on_cancel() calls will return FALSE.
1941 g_atomic_int_set (&state, 0);
1942 callback_ran = FALSE;
1943 notification_emitted = FALSE;
1944 task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran);
1945 g_task_set_return_on_cancel (task, TRUE);
1946 g_signal_connect (task, "notify::completed",
1947 (GCallback) completed_cb, ¬ification_emitted);
1949 g_task_set_task_data (task, (gpointer)&state, NULL);
1950 g_task_run_in_thread (task, return_on_cancel_atomic_thread);
1952 g_assert_cmpint (g_atomic_int_get (&state), ==, 0);
1954 while (g_atomic_int_get (&state) == 0)
1955 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1956 g_assert_cmpint (g_atomic_int_get (&state), ==, 1);
1957 g_assert (g_task_get_return_on_cancel (task));
1959 while (g_atomic_int_get (&state) == 1)
1960 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1961 g_assert_cmpint (g_atomic_int_get (&state), ==, 2);
1962 g_assert (!g_task_get_return_on_cancel (task));
1964 g_cancellable_cancel (cancellable);
1965 g_idle_add (idle_quit_loop, NULL);
1966 g_main_loop_run (loop);
1967 g_assert (callback_ran == FALSE);
1969 while (g_atomic_int_get (&state) == 2)
1970 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1971 g_assert_cmpint (g_atomic_int_get (&state), ==, 5);
1972 g_assert (!g_task_get_return_on_cancel (task));
1974 g_main_loop_run (loop);
1975 g_assert (callback_ran == TRUE);
1976 g_assert_true (notification_emitted);
1978 while (g_atomic_int_get (&state) == 5)
1979 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1980 g_assert_cmpint (g_atomic_int_get (&state), ==, 7);
1982 g_object_unref (cancellable);
1983 g_mutex_unlock (&roca_mutex_1);
1984 g_mutex_unlock (&roca_mutex_2);
1985 g_object_unref (task);
1988 /* test_return_pointer: memory management of pointer returns */
1991 test_return_pointer (void)
1993 GObject *object, *ret;
1995 GCancellable *cancellable;
1996 GError *error = NULL;
1998 /* If we don't read back the return value, the task will
1999 * run its destroy notify.
2001 object = (GObject *)g_dummy_object_new ();
2002 g_assert_cmpint (object->ref_count, ==, 1);
2003 g_object_add_weak_pointer (object, (gpointer *)&object);
2005 task = g_task_new (NULL, NULL, NULL, NULL);
2006 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
2007 g_task_return_pointer (task, object, g_object_unref);
2008 g_assert_cmpint (object->ref_count, ==, 1);
2010 /* Task and object are reffed until the :completed notification in idle. */
2011 g_object_unref (task);
2012 g_assert_nonnull (task);
2013 g_assert_nonnull (object);
2015 wait_for_completed_notification (task);
2017 g_assert_null (task);
2018 g_assert_null (object);
2020 /* Likewise, if the return value is overwritten by an error */
2021 object = (GObject *)g_dummy_object_new ();
2022 g_assert_cmpint (object->ref_count, ==, 1);
2023 g_object_add_weak_pointer (object, (gpointer *)&object);
2025 cancellable = g_cancellable_new ();
2026 task = g_task_new (NULL, cancellable, NULL, NULL);
2027 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
2028 g_task_return_pointer (task, object, g_object_unref);
2029 g_assert_cmpint (object->ref_count, ==, 1);
2030 g_cancellable_cancel (cancellable);
2031 g_assert_cmpint (object->ref_count, ==, 1);
2033 ret = g_task_propagate_pointer (task, &error);
2034 g_assert (ret == NULL);
2035 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
2036 g_clear_error (&error);
2037 g_assert_cmpint (object->ref_count, ==, 1);
2039 g_object_unref (task);
2040 g_object_unref (cancellable);
2041 g_assert_nonnull (task);
2042 g_assert_nonnull (object);
2044 wait_for_completed_notification (task);
2046 g_assert_null (task);
2047 g_assert_null (object);
2049 /* If we read back the return value, we steal its ref */
2050 object = (GObject *)g_dummy_object_new ();
2051 g_assert_cmpint (object->ref_count, ==, 1);
2052 g_object_add_weak_pointer (object, (gpointer *)&object);
2054 task = g_task_new (NULL, NULL, NULL, NULL);
2055 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
2056 g_task_return_pointer (task, object, g_object_unref);
2057 g_assert_cmpint (object->ref_count, ==, 1);
2059 ret = g_task_propagate_pointer (task, &error);
2060 g_assert_no_error (error);
2061 g_assert (ret == object);
2062 g_assert_cmpint (object->ref_count, ==, 1);
2064 g_object_unref (task);
2065 g_assert_nonnull (task);
2066 g_assert_cmpint (object->ref_count, ==, 1);
2067 g_object_unref (object);
2068 g_assert (object == NULL);
2070 wait_for_completed_notification (task);
2071 g_assert_null (task);
2075 test_return_value (void)
2078 GValue value = G_VALUE_INIT;
2079 GValue ret = G_VALUE_INIT;
2081 GError *error = NULL;
2083 object = (GObject *)g_dummy_object_new ();
2084 g_assert_cmpint (object->ref_count, ==, 1);
2085 g_object_add_weak_pointer (object, (gpointer *)&object);
2087 g_value_init (&value, G_TYPE_OBJECT);
2088 g_value_set_object (&value, object);
2089 g_assert_cmpint (object->ref_count, ==, 2);
2091 task = g_task_new (NULL, NULL, NULL, NULL);
2092 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
2093 g_task_return_value (task, &value);
2094 g_assert_cmpint (object->ref_count, ==, 3);
2096 g_assert_true (g_task_propagate_value (task, &ret, &error));
2097 g_assert_no_error (error);
2098 g_assert_true (g_value_get_object (&ret) == object);
2099 g_assert_cmpint (object->ref_count, ==, 3);
2101 g_object_unref (task);
2102 g_assert_nonnull (task);
2103 wait_for_completed_notification (task);
2104 g_assert_null (task);
2106 g_assert_cmpint (object->ref_count, ==, 3);
2107 g_value_unset (&ret);
2108 g_assert_cmpint (object->ref_count, ==, 2);
2109 g_value_unset (&value);
2110 g_assert_cmpint (object->ref_count, ==, 1);
2111 g_object_unref (object);
2112 g_assert_null (object);
2115 /* test_object_keepalive: GTask takes a ref on its source object */
2117 static GObject *keepalive_object;
2120 keepalive_callback (GObject *object,
2121 GAsyncResult *result,
2124 gssize *result_out = user_data;
2125 GError *error = NULL;
2127 g_assert (object == keepalive_object);
2128 g_assert (g_task_is_valid (result, object));
2129 g_assert (g_async_result_get_user_data (result) == user_data);
2130 g_assert (!g_task_had_error (G_TASK (result)));
2131 g_assert_false (g_task_get_completed (G_TASK (result)));
2133 *result_out = g_task_propagate_int (G_TASK (result), &error);
2134 g_assert_no_error (error);
2136 g_assert (!g_task_had_error (G_TASK (result)));
2138 g_main_loop_quit (loop);
2142 test_object_keepalive (void)
2148 gboolean notification_emitted = FALSE;
2150 keepalive_object = object = (GObject *)g_dummy_object_new ();
2151 g_object_add_weak_pointer (object, (gpointer *)&object);
2153 task = g_task_new (object, NULL, keepalive_callback, &result);
2154 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
2155 g_signal_connect (task, "notify::completed",
2156 (GCallback) completed_cb, ¬ification_emitted);
2158 ref_count = object->ref_count;
2159 g_assert_cmpint (ref_count, >, 1);
2161 g_assert (g_task_get_source_object (task) == object);
2162 g_assert (g_async_result_get_source_object (G_ASYNC_RESULT (task)) == object);
2163 g_assert_cmpint (object->ref_count, ==, ref_count + 1);
2164 g_object_unref (object);
2166 g_object_unref (object);
2167 g_assert (object != NULL);
2169 g_task_return_int (task, magic);
2170 g_main_loop_run (loop);
2172 g_assert (object != NULL);
2173 g_assert_cmpint (result, ==, magic);
2174 g_assert_true (notification_emitted);
2176 g_object_unref (task);
2177 g_assert (task == NULL);
2178 g_assert (object == NULL);
2181 /* test_legacy_error: legacy GSimpleAsyncResult handling */
2182 static void test_legacy_error (void);
2185 legacy_error_callback (GObject *object,
2186 GAsyncResult *result,
2189 gssize *result_out = user_data;
2190 GError *error = NULL;
2192 g_assert (object == NULL);
2193 g_assert (g_async_result_is_tagged (result, test_legacy_error));
2194 g_assert (g_async_result_get_user_data (result) == user_data);
2196 if (g_async_result_legacy_propagate_error (result, &error))
2198 g_assert (!g_task_is_valid (result, object));
2199 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2200 g_assert (g_simple_async_result_is_valid (result, object, test_legacy_error));
2201 G_GNUC_END_IGNORE_DEPRECATIONS;
2203 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
2205 g_clear_error (&error);
2209 g_assert (g_task_is_valid (result, object));
2211 *result_out = g_task_propagate_int (G_TASK (result), NULL);
2212 /* Might be error, might not */
2215 g_main_loop_quit (loop);
2219 legacy_error_return (gpointer user_data)
2221 if (G_IS_TASK (user_data))
2223 GTask *task = user_data;
2225 g_task_return_int (task, magic);
2226 g_object_unref (task);
2230 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
2232 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2233 g_simple_async_result_set_error (simple,
2237 g_simple_async_result_complete (simple);
2238 G_GNUC_END_IGNORE_DEPRECATIONS;
2239 g_object_unref (simple);
2246 test_legacy_error (void)
2249 GSimpleAsyncResult *simple;
2253 task = g_task_new (NULL, NULL, legacy_error_callback, &result);
2254 g_task_set_source_tag (task, test_legacy_error);
2255 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
2257 g_idle_add (legacy_error_return, task);
2258 g_main_loop_run (loop);
2260 g_assert_cmpint (result, ==, magic);
2261 g_assert (task == NULL);
2264 task = g_task_new (NULL, NULL, legacy_error_callback, &result);
2265 g_task_set_source_tag (task, test_legacy_error);
2266 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
2268 g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
2270 g_object_unref (task);
2271 g_main_loop_run (loop);
2273 g_assert_cmpint (result, ==, -1);
2274 g_assert (task == NULL);
2276 /* GSimpleAsyncResult error */
2277 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2278 simple = g_simple_async_result_new (NULL, legacy_error_callback, &result,
2280 G_GNUC_END_IGNORE_DEPRECATIONS;
2281 g_object_add_weak_pointer (G_OBJECT (simple), (gpointer *)&simple);
2283 g_idle_add (legacy_error_return, simple);
2284 g_main_loop_run (loop);
2286 g_assert_cmpint (result, ==, -2);
2287 g_assert (simple == NULL);
2290 /* Various helper functions for the return tests below. */
2292 task_complete_cb (GObject *source,
2293 GAsyncResult *result,
2296 GTask *task = G_TASK (result);
2297 guint *calls = user_data;
2299 g_assert_cmpint (++*calls, <=, 1);
2301 /* Propagate the result, so it’s removed from the task’s internal state. */
2302 g_task_propagate_boolean (task, NULL);
2306 return_twice (GTask *task)
2308 gboolean error_first = GPOINTER_TO_UINT (g_task_get_task_data (task));
2312 g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_UNKNOWN, "oh no");
2313 g_task_return_boolean (task, TRUE);
2317 g_task_return_boolean (task, TRUE);
2318 g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_UNKNOWN, "oh no");
2323 idle_cb (gpointer user_data)
2325 GTask *task = user_data;
2326 return_twice (task);
2327 g_object_unref (task);
2329 return G_SOURCE_REMOVE;
2333 test_return_permutation (gboolean error_first,
2334 gboolean return_in_idle)
2339 g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1525");
2341 task = g_task_new (NULL, NULL, task_complete_cb, &calls);
2342 g_task_set_task_data (task, GUINT_TO_POINTER (error_first), NULL);
2345 g_idle_add (idle_cb, g_object_ref (task));
2347 return_twice (task);
2350 g_main_context_iteration (NULL, TRUE);
2352 g_assert_cmpint (calls, ==, 1);
2354 g_object_unref (task);
2357 /* Test that calling g_task_return_boolean() after g_task_return_error(), when
2358 * returning in an idle callback, correctly results in a critical warning. */
2360 test_return_in_idle_error_first (void)
2362 if (g_test_subprocess ())
2364 test_return_permutation (TRUE, TRUE);
2368 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
2369 g_test_trap_assert_failed ();
2370 g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*");
2373 /* Test that calling g_task_return_error() after g_task_return_boolean(), when
2374 * returning in an idle callback, correctly results in a critical warning. */
2376 test_return_in_idle_value_first (void)
2378 if (g_test_subprocess ())
2380 test_return_permutation (FALSE, TRUE);
2384 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
2385 g_test_trap_assert_failed ();
2386 g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*");
2389 /* Test that calling g_task_return_boolean() after g_task_return_error(), when
2390 * returning synchronously, correctly results in a critical warning. */
2392 test_return_error_first (void)
2394 if (g_test_subprocess ())
2396 test_return_permutation (TRUE, FALSE);
2400 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
2401 g_test_trap_assert_failed ();
2402 g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*");
2405 /* Test that calling g_task_return_error() after g_task_return_boolean(), when
2406 * returning synchronously, correctly results in a critical warning. */
2408 test_return_value_first (void)
2410 if (g_test_subprocess ())
2412 test_return_permutation (FALSE, FALSE);
2416 g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
2417 g_test_trap_assert_failed ();
2418 g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*");
2422 source_cb (gpointer user_data)
2424 return G_SOURCE_REMOVE;
2428 test_attach_source_set_name (void)
2432 GSource *source = NULL;
2433 GSourceFuncs source_funcs = { NULL, NULL, NULL, NULL, NULL, NULL };
2435 g_test_summary ("Test that attaching a source to a task will set the source’s name if unset");
2437 task = g_task_new (NULL, NULL, task_complete_cb, &calls);
2438 g_task_set_name (task, "test name");
2440 source = g_source_new (&source_funcs, sizeof (GSource));
2441 g_task_attach_source (task, source, source_cb);
2442 g_assert_cmpstr (g_source_get_name (source), ==, "test name");
2443 g_source_unref (source);
2445 source = g_source_new (&source_funcs, sizeof (GSource));
2446 g_source_set_name (source, "not the task name");
2447 g_task_attach_source (task, source, source_cb);
2448 g_assert_cmpstr (g_source_get_name (source), ==, "not the task name");
2449 g_source_unref (source);
2451 g_object_unref (task);
2455 test_finalize_without_return (void)
2460 /* With a callback set. */
2461 task = g_task_new (NULL, NULL, task_complete_cb, &n_calls);
2463 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2464 "GTask * (source object: *, source tag: *) finalized without "
2465 "ever returning (using g_task_return_*()). This potentially "
2466 "indicates a bug in the program.");
2467 g_object_unref (task);
2468 g_test_assert_expected_messages ();
2470 /* With a callback and task name set. */
2471 task = g_task_new (NULL, NULL, task_complete_cb, &n_calls);
2472 g_task_set_static_name (task, "oogly boogly");
2474 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2475 "GTask oogly boogly (source object: *, source tag: *) finalized without "
2476 "ever returning (using g_task_return_*()). This potentially "
2477 "indicates a bug in the program.");
2478 g_object_unref (task);
2479 g_test_assert_expected_messages ();
2481 /* Without a callback set. */
2482 task = g_task_new (NULL, NULL, NULL, NULL);
2484 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
2485 "GTask * (source object: *, source tag: *) finalized without "
2486 "ever returning (using g_task_return_*()). This potentially "
2487 "indicates a bug in the program.");
2488 g_object_unref (task);
2489 g_test_assert_expected_messages ();
2493 main (int argc, char **argv)
2497 g_test_init (&argc, &argv, NULL);
2499 loop = g_main_loop_new (NULL, FALSE);
2500 main_thread = g_thread_self ();
2501 magic = g_get_monotonic_time ();
2503 g_test_add_func ("/gtask/basic", test_basic);
2504 g_test_add_func ("/gtask/error", test_error);
2505 g_test_add_func ("/gtask/return-from-same-iteration", test_return_from_same_iteration);
2506 g_test_add_func ("/gtask/return-from-toplevel", test_return_from_toplevel);
2507 g_test_add_func ("/gtask/return-from-anon-thread", test_return_from_anon_thread);
2508 g_test_add_func ("/gtask/return-from-wrong-thread", test_return_from_wrong_thread);
2509 g_test_add_func ("/gtask/no-callback", test_no_callback);
2510 g_test_add_func ("/gtask/report-error", test_report_error);
2511 g_test_add_func ("/gtask/priority", test_priority);
2512 g_test_add_func ("/gtask/name", test_name);
2513 g_test_add_func ("/gtask/name/macro-wrapper", test_name_macro_wrapper);
2514 g_test_add_func ("/gtask/static-name", test_static_name);
2515 g_test_add_func ("/gtask/asynchronous-cancellation", test_asynchronous_cancellation);
2516 g_test_add_func ("/gtask/check-cancellable", test_check_cancellable);
2517 g_test_add_func ("/gtask/return-if-cancelled", test_return_if_cancelled);
2518 g_test_add_func ("/gtask/run-in-thread", test_run_in_thread);
2519 g_test_add_func ("/gtask/run-in-thread-sync", test_run_in_thread_sync);
2520 g_test_add_func ("/gtask/run-in-thread-priority", test_run_in_thread_priority);
2521 g_test_add_func ("/gtask/run-in-thread-nested", test_run_in_thread_nested);
2522 g_test_add_func ("/gtask/run-in-thread-overflow", test_run_in_thread_overflow);
2523 g_test_add_func ("/gtask/return-on-cancel", test_return_on_cancel);
2524 g_test_add_func ("/gtask/return-on-cancel-sync", test_return_on_cancel_sync);
2525 g_test_add_func ("/gtask/return-on-cancel-atomic", test_return_on_cancel_atomic);
2526 g_test_add_func ("/gtask/return-pointer", test_return_pointer);
2527 g_test_add_func ("/gtask/return-value", test_return_value);
2528 g_test_add_func ("/gtask/object-keepalive", test_object_keepalive);
2529 g_test_add_func ("/gtask/legacy-error", test_legacy_error);
2530 g_test_add_func ("/gtask/return/in-idle/error-first", test_return_in_idle_error_first);
2531 g_test_add_func ("/gtask/return/in-idle/value-first", test_return_in_idle_value_first);
2532 g_test_add_func ("/gtask/return/error-first", test_return_error_first);
2533 g_test_add_func ("/gtask/return/value-first", test_return_value_first);
2534 g_test_add_func ("/gtask/attach-source/set-name", test_attach_source_set_name);
2535 g_test_add_func ("/gtask/finalize-without-return", test_finalize_without_return);
2539 g_main_loop_unref (loop);