2 * Copyright 2012 Red Hat, Inc.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2 of the licence or (at
7 * your option) any later version.
9 * See the included COPYING file for more information.
14 static GMainLoop *loop;
15 static GThread *main_thread;
18 /* We need objects for a few tests where we don't care what type
19 * they are, just that they're GObjects.
21 #define g_dummy_object_new g_socket_client_new
26 basic_callback (GObject *object,
30 gssize *result_out = user_data;
33 g_assert (object == NULL);
34 g_assert (g_task_is_valid (result, object));
35 g_assert (g_async_result_get_user_data (result) == user_data);
36 g_assert (!g_task_had_error (G_TASK (result)));
38 *result_out = g_task_propagate_int (G_TASK (result), &error);
39 g_assert_no_error (error);
41 g_main_loop_quit (loop);
45 basic_return (gpointer user_data)
47 GTask *task = user_data;
49 g_task_return_int (task, magic);
50 g_object_unref (task);
56 basic_destroy_notify (gpointer user_data)
58 gboolean *destroyed = user_data;
68 gboolean task_data_destroyed = FALSE;
70 task = g_task_new (NULL, NULL, basic_callback, &result);
71 g_task_set_task_data (task, &task_data_destroyed, basic_destroy_notify);
72 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
74 g_idle_add (basic_return, task);
75 g_main_loop_run (loop);
77 g_assert_cmpint (result, ==, magic);
78 g_assert (task_data_destroyed == TRUE);
79 g_assert (task == NULL);
85 error_callback (GObject *object,
89 gssize *result_out = user_data;
92 g_assert (object == NULL);
93 g_assert (g_task_is_valid (result, object));
94 g_assert (g_async_result_get_user_data (result) == user_data);
95 g_assert (g_task_had_error (G_TASK (result)));
97 *result_out = g_task_propagate_int (G_TASK (result), &error);
98 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
101 g_main_loop_quit (loop);
105 error_return (gpointer user_data)
107 GTask *task = user_data;
109 g_task_return_new_error (task,
110 G_IO_ERROR, G_IO_ERROR_FAILED,
112 g_object_unref (task);
118 error_destroy_notify (gpointer user_data)
120 gboolean *destroyed = user_data;
130 gboolean first_task_data_destroyed = FALSE;
131 gboolean second_task_data_destroyed = FALSE;
133 task = g_task_new (NULL, NULL, error_callback, &result);
134 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
136 g_assert (first_task_data_destroyed == FALSE);
137 g_task_set_task_data (task, &first_task_data_destroyed, error_destroy_notify);
138 g_assert (first_task_data_destroyed == FALSE);
140 /* Calling g_task_set_task_data() again will destroy the first data */
141 g_task_set_task_data (task, &second_task_data_destroyed, error_destroy_notify);
142 g_assert (first_task_data_destroyed == TRUE);
143 g_assert (second_task_data_destroyed == FALSE);
145 g_idle_add (error_return, task);
146 g_main_loop_run (loop);
148 g_assert_cmpint (result, ==, -1);
149 g_assert (second_task_data_destroyed == TRUE);
150 g_assert (task == NULL);
153 /* test_return_from_same_iteration: calling g_task_return_* from the
154 * loop iteration the task was created in defers completion until the
157 gboolean same_result = FALSE;
160 same_callback (GObject *object,
161 GAsyncResult *result,
164 gboolean *result_out = user_data;
165 GError *error = NULL;
167 g_assert (object == NULL);
168 g_assert (g_task_is_valid (result, object));
169 g_assert (g_async_result_get_user_data (result) == user_data);
170 g_assert (!g_task_had_error (G_TASK (result)));
172 *result_out = g_task_propagate_boolean (G_TASK (result), &error);
173 g_assert_no_error (error);
175 g_main_loop_quit (loop);
179 same_start (gpointer user_data)
181 gpointer *weak_pointer = user_data;
184 task = g_task_new (NULL, NULL, same_callback, &same_result);
185 *weak_pointer = task;
186 g_object_add_weak_pointer (G_OBJECT (task), weak_pointer);
188 g_task_return_boolean (task, TRUE);
189 g_object_unref (task);
191 /* same_callback should not have been invoked yet */
192 g_assert (same_result == FALSE);
193 g_assert (*weak_pointer == task);
199 test_return_from_same_iteration (void)
201 gpointer weak_pointer;
203 g_idle_add (same_start, &weak_pointer);
204 g_main_loop_run (loop);
206 g_assert (same_result == TRUE);
207 g_assert (weak_pointer == NULL);
210 /* test_return_from_toplevel: calling g_task_return_* from outside any
211 * main loop completes the task inside the main loop.
215 toplevel_callback (GObject *object,
216 GAsyncResult *result,
219 gboolean *result_out = user_data;
220 GError *error = NULL;
222 g_assert (object == NULL);
223 g_assert (g_task_is_valid (result, object));
224 g_assert (g_async_result_get_user_data (result) == user_data);
225 g_assert (!g_task_had_error (G_TASK (result)));
227 *result_out = g_task_propagate_boolean (G_TASK (result), &error);
228 g_assert_no_error (error);
230 g_main_loop_quit (loop);
234 test_return_from_toplevel (void)
237 gboolean result = FALSE;
239 task = g_task_new (NULL, NULL, toplevel_callback, &result);
240 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
242 g_task_return_boolean (task, TRUE);
243 g_object_unref (task);
245 /* toplevel_callback should not have been invoked yet */
246 g_assert (result == FALSE);
247 g_assert (task != NULL);
249 g_main_loop_run (loop);
251 g_assert (result == TRUE);
252 g_assert (task == NULL);
255 /* test_return_from_anon_thread: calling g_task_return_* from a
256 * thread with no thread-default main context will complete the
257 * task in the task's context/thread.
260 GThread *anon_thread;
263 anon_callback (GObject *object,
264 GAsyncResult *result,
267 gssize *result_out = user_data;
268 GError *error = NULL;
270 g_assert (object == NULL);
271 g_assert (g_task_is_valid (result, object));
272 g_assert (g_async_result_get_user_data (result) == user_data);
273 g_assert (!g_task_had_error (G_TASK (result)));
275 g_assert (g_thread_self () == main_thread);
277 *result_out = g_task_propagate_int (G_TASK (result), &error);
278 g_assert_no_error (error);
280 g_main_loop_quit (loop);
284 anon_thread_func (gpointer user_data)
286 GTask *task = user_data;
288 g_task_return_int (task, magic);
289 g_object_unref (task);
295 anon_start (gpointer user_data)
297 GTask *task = user_data;
299 anon_thread = g_thread_new ("test_return_from_anon_thread",
300 anon_thread_func, task);
305 test_return_from_anon_thread (void)
310 task = g_task_new (NULL, NULL, anon_callback, &result);
311 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
313 g_idle_add (anon_start, task);
314 g_main_loop_run (loop);
316 g_thread_join (anon_thread);
318 g_assert_cmpint (result, ==, magic);
319 g_assert (task == NULL);
322 /* test_return_from_wrong_thread: calling g_task_return_* from a
323 * thread with its own thread-default main context will complete the
324 * task in the task's context/thread.
327 GThread *wrong_thread;
330 wrong_callback (GObject *object,
331 GAsyncResult *result,
334 gssize *result_out = user_data;
335 GError *error = NULL;
337 g_assert (object == NULL);
338 g_assert (g_task_is_valid (result, object));
339 g_assert (g_async_result_get_user_data (result) == user_data);
340 g_assert (!g_task_had_error (G_TASK (result)));
342 g_assert (g_thread_self () == main_thread);
344 *result_out = g_task_propagate_int (G_TASK (result), &error);
345 g_assert_no_error (error);
347 g_main_loop_quit (loop);
351 wrong_thread_func (gpointer user_data)
353 GTask *task = user_data;
354 GMainContext *context;
356 context = g_main_context_new ();
357 g_main_context_push_thread_default (context);
359 g_assert (g_task_get_context (task) != context);
361 g_task_return_int (task, magic);
362 g_object_unref (task);
364 g_main_context_pop_thread_default (context);
365 g_main_context_unref (context);
371 wrong_start (gpointer user_data)
373 GTask *task = user_data;
375 wrong_thread = g_thread_new ("test_return_from_anon_thread",
376 wrong_thread_func, task);
381 test_return_from_wrong_thread (void)
386 task = g_task_new (NULL, NULL, wrong_callback, &result);
387 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
389 g_idle_add (wrong_start, task);
390 g_main_loop_run (loop);
392 g_thread_join (wrong_thread);
394 g_assert_cmpint (result, ==, magic);
395 g_assert (task == NULL);
398 /* test_no_callback */
401 test_no_callback (void)
405 task = g_task_new (NULL, NULL, NULL, NULL);
406 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
408 g_task_return_boolean (task, TRUE);
409 g_object_unref (task);
411 /* Since there's no callback, g_task_return_boolean() will
412 * not have queued an idle source and taken a ref on task,
413 * so we just dropped the last ref.
415 g_assert (task == NULL);
418 /* test_report_error */
420 static void test_report_error (void);
423 report_callback (GObject *object,
424 GAsyncResult *result,
427 gpointer *weak_pointer = user_data;
428 GError *error = NULL;
431 g_assert (object == NULL);
432 g_assert (g_task_is_valid (result, object));
433 g_assert (g_async_result_get_user_data (result) == user_data);
434 g_assert (g_async_result_is_tagged (result, test_report_error));
435 g_assert (g_task_get_source_tag (G_TASK (result)) == test_report_error);
436 g_assert (g_task_had_error (G_TASK (result)));
438 ret = g_task_propagate_int (G_TASK (result), &error);
439 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
440 g_assert_cmpint (ret, ==, -1);
441 g_error_free (error);
443 *weak_pointer = result;
444 g_object_add_weak_pointer (G_OBJECT (result), weak_pointer);
446 g_main_loop_quit (loop);
450 test_report_error (void)
452 gpointer weak_pointer = (gpointer)-1;
454 g_task_report_new_error (NULL, report_callback, &weak_pointer,
456 G_IO_ERROR, G_IO_ERROR_FAILED,
458 g_main_loop_run (loop);
460 g_assert (weak_pointer == NULL);
463 /* test_priority: tasks complete in priority order */
465 static int counter = 0;
468 priority_callback (GObject *object,
469 GAsyncResult *result,
472 gssize *ret_out = user_data;
473 GError *error = NULL;
475 g_assert (object == NULL);
476 g_assert (g_task_is_valid (result, object));
477 g_assert (g_async_result_get_user_data (result) == user_data);
478 g_assert (!g_task_had_error (G_TASK (result)));
480 g_task_propagate_boolean (G_TASK (result), &error);
481 g_assert_no_error (error);
483 *ret_out = ++counter;
486 g_main_loop_quit (loop);
493 gssize ret1, ret2, ret3;
495 /* t2 has higher priority than either t1 or t3, so we can't
496 * accidentally pass the test just by completing the tasks in the
497 * order they were created (or in reverse order).
500 t1 = g_task_new (NULL, NULL, priority_callback, &ret1);
501 g_task_set_priority (t1, G_PRIORITY_DEFAULT);
502 g_task_return_boolean (t1, TRUE);
505 t2 = g_task_new (NULL, NULL, priority_callback, &ret2);
506 g_task_set_priority (t2, G_PRIORITY_HIGH);
507 g_task_return_boolean (t2, TRUE);
510 t3 = g_task_new (NULL, NULL, priority_callback, &ret3);
511 g_task_set_priority (t3, G_PRIORITY_LOW);
512 g_task_return_boolean (t3, TRUE);
515 g_main_loop_run (loop);
517 g_assert_cmpint (ret2, ==, 1);
518 g_assert_cmpint (ret1, ==, 2);
519 g_assert_cmpint (ret3, ==, 3);
522 /* test_check_cancellable: cancellation overrides return value */
525 CANCEL_BEFORE = (1 << 1),
526 CANCEL_AFTER = (1 << 2),
527 CHECK_CANCELLABLE = (1 << 3)
529 #define NUM_CANCEL_TESTS (CANCEL_BEFORE | CANCEL_AFTER | CHECK_CANCELLABLE)
532 cancel_callback (GObject *object,
533 GAsyncResult *result,
536 int state = GPOINTER_TO_INT (user_data);
538 GCancellable *cancellable;
539 GError *error = NULL;
541 g_assert (object == NULL);
542 g_assert (g_task_is_valid (result, object));
543 g_assert (g_async_result_get_user_data (result) == user_data);
545 task = G_TASK (result);
546 cancellable = g_task_get_cancellable (task);
547 g_assert (G_IS_CANCELLABLE (cancellable));
549 if (state & (CANCEL_BEFORE | CANCEL_AFTER))
550 g_assert (g_cancellable_is_cancelled (cancellable));
552 g_assert (!g_cancellable_is_cancelled (cancellable));
554 if (state & CHECK_CANCELLABLE)
555 g_assert (g_task_get_check_cancellable (task));
557 g_assert (!g_task_get_check_cancellable (task));
559 if (g_task_propagate_boolean (task, &error))
561 g_assert (!g_cancellable_is_cancelled (cancellable) ||
562 !g_task_get_check_cancellable (task));
566 g_assert (g_cancellable_is_cancelled (cancellable) &&
567 g_task_get_check_cancellable (task));
568 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
569 g_error_free (error);
572 g_main_loop_quit (loop);
576 test_check_cancellable (void)
579 GCancellable *cancellable;
582 cancellable = g_cancellable_new ();
584 for (state = 0; state <= NUM_CANCEL_TESTS; state++)
586 task = g_task_new (NULL, cancellable, cancel_callback,
587 GINT_TO_POINTER (state));
588 g_task_set_check_cancellable (task, (state & CHECK_CANCELLABLE) != 0);
590 if (state & CANCEL_BEFORE)
591 g_cancellable_cancel (cancellable);
592 g_task_return_boolean (task, TRUE);
593 if (state & CANCEL_AFTER)
594 g_cancellable_cancel (cancellable);
596 g_main_loop_run (loop);
597 g_object_unref (task);
598 g_cancellable_reset (cancellable);
601 g_object_unref (cancellable);
604 /* test_return_if_cancelled */
607 return_if_cancelled_callback (GObject *object,
608 GAsyncResult *result,
611 GError *error = NULL;
613 g_assert (object == NULL);
614 g_assert (g_task_is_valid (result, object));
615 g_assert (g_async_result_get_user_data (result) == user_data);
616 g_assert (g_task_had_error (G_TASK (result)));
618 g_task_propagate_boolean (G_TASK (result), &error);
619 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
620 g_clear_error (&error);
622 g_main_loop_quit (loop);
626 test_return_if_cancelled (void)
629 GCancellable *cancellable;
632 cancellable = g_cancellable_new ();
634 task = g_task_new (NULL, cancellable, return_if_cancelled_callback, NULL);
635 g_cancellable_cancel (cancellable);
636 cancelled = g_task_return_error_if_cancelled (task);
637 g_assert (cancelled);
638 g_main_loop_run (loop);
639 g_object_unref (task);
640 g_cancellable_reset (cancellable);
642 task = g_task_new (NULL, cancellable, return_if_cancelled_callback, NULL);
643 g_task_set_check_cancellable (task, FALSE);
644 g_cancellable_cancel (cancellable);
645 cancelled = g_task_return_error_if_cancelled (task);
646 g_assert (cancelled);
647 g_main_loop_run (loop);
648 g_object_unref (task);
649 g_object_unref (cancellable);
652 /* test_run_in_thread */
655 run_in_thread_callback (GObject *object,
656 GAsyncResult *result,
659 gboolean *done = user_data;
660 GError *error = NULL;
663 g_assert (g_thread_self () == main_thread);
665 g_assert (object == NULL);
666 g_assert (g_task_is_valid (result, object));
667 g_assert (g_async_result_get_user_data (result) == user_data);
668 g_assert (!g_task_had_error (G_TASK (result)));
670 ret = g_task_propagate_int (G_TASK (result), &error);
671 g_assert_no_error (error);
672 g_assert_cmpint (ret, ==, magic);
675 g_main_loop_quit (loop);
679 run_in_thread_thread (GTask *task,
680 gpointer source_object,
682 GCancellable *cancellable)
684 gboolean *thread_ran = task_data;
686 g_assert (source_object == g_task_get_source_object (task));
687 g_assert (task_data == g_task_get_task_data (task));
688 g_assert (cancellable == g_task_get_cancellable (task));
690 g_assert (g_thread_self () != main_thread);
693 g_task_return_int (task, magic);
697 test_run_in_thread (void)
700 volatile gboolean thread_ran = FALSE;
701 gboolean done = FALSE;
703 task = g_task_new (NULL, NULL, run_in_thread_callback, &done);
704 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
706 g_task_set_task_data (task, (gpointer)&thread_ran, NULL);
707 g_task_run_in_thread (task, run_in_thread_thread);
708 g_object_unref (task);
713 g_assert (done == FALSE);
714 g_assert (task != NULL);
716 g_main_loop_run (loop);
718 g_assert (done == TRUE);
719 g_assert (task == NULL);
722 /* test_run_in_thread_sync */
725 run_in_thread_sync_callback (GObject *object,
726 GAsyncResult *result,
729 /* g_task_run_in_thread_sync() does not invoke the task's callback */
730 g_assert_not_reached ();
734 run_in_thread_sync_thread (GTask *task,
735 gpointer source_object,
737 GCancellable *cancellable)
739 gboolean *thread_ran = task_data;
741 g_assert (source_object == g_task_get_source_object (task));
742 g_assert (task_data == g_task_get_task_data (task));
743 g_assert (cancellable == g_task_get_cancellable (task));
745 g_assert (g_thread_self () != main_thread);
748 g_task_return_int (task, magic);
752 test_run_in_thread_sync (void)
755 gboolean thread_ran = FALSE;
757 GError *error = NULL;
759 task = g_task_new (NULL, NULL, run_in_thread_sync_callback, NULL);
761 g_task_set_task_data (task, &thread_ran, NULL);
762 g_task_run_in_thread_sync (task, run_in_thread_sync_thread);
764 g_assert (thread_ran == TRUE);
765 g_assert (task != NULL);
766 g_assert (!g_task_had_error (task));
768 ret = g_task_propagate_int (task, &error);
769 g_assert_no_error (error);
770 g_assert_cmpint (ret, ==, magic);
772 g_object_unref (task);
775 /* test_run_in_thread_priority */
777 static GMutex fake_task_mutex, last_fake_task_mutex;
778 static gint sequence_number = 0;
781 quit_main_loop_callback (GObject *object,
782 GAsyncResult *result,
785 GError *error = NULL;
788 g_assert (g_thread_self () == main_thread);
790 g_assert (object == NULL);
791 g_assert (g_task_is_valid (result, object));
792 g_assert (g_async_result_get_user_data (result) == user_data);
793 g_assert (!g_task_had_error (G_TASK (result)));
795 ret = g_task_propagate_boolean (G_TASK (result), &error);
796 g_assert_no_error (error);
797 g_assert_cmpint (ret, ==, TRUE);
799 g_main_loop_quit (loop);
803 set_sequence_number_thread (GTask *task,
804 gpointer source_object,
806 GCancellable *cancellable)
808 gint *seq_no_p = task_data;
810 *seq_no_p = ++sequence_number;
811 g_task_return_boolean (task, TRUE);
815 fake_task_thread (GTask *task,
816 gpointer source_object,
818 GCancellable *cancellable)
820 GMutex *mutex = task_data;
822 g_mutex_lock (mutex);
823 g_mutex_unlock (mutex);
824 g_task_return_boolean (task, TRUE);
827 #define G_TASK_THREAD_POOL_SIZE 10
828 static int fake_tasks_running;
831 fake_task_callback (GObject *source,
832 GAsyncResult *result,
835 if (--fake_tasks_running == 0)
836 g_main_loop_quit (loop);
840 clog_up_thread_pool (void)
845 g_thread_pool_stop_unused_threads ();
847 g_mutex_lock (&fake_task_mutex);
848 for (i = 0; i < G_TASK_THREAD_POOL_SIZE - 1; i++)
850 task = g_task_new (NULL, NULL, fake_task_callback, NULL);
851 g_task_set_task_data (task, &fake_task_mutex, NULL);
852 g_assert_cmpint (g_task_get_priority (task), ==, G_PRIORITY_DEFAULT);
853 g_task_set_priority (task, G_PRIORITY_HIGH * 2);
854 g_assert_cmpint (g_task_get_priority (task), ==, G_PRIORITY_HIGH * 2);
855 g_task_run_in_thread (task, fake_task_thread);
856 g_object_unref (task);
857 fake_tasks_running++;
860 g_mutex_lock (&last_fake_task_mutex);
861 task = g_task_new (NULL, NULL, NULL, NULL);
862 g_task_set_task_data (task, &last_fake_task_mutex, NULL);
863 g_task_set_priority (task, G_PRIORITY_HIGH * 2);
864 g_task_run_in_thread (task, fake_task_thread);
865 g_object_unref (task);
869 unclog_thread_pool (void)
871 g_mutex_unlock (&fake_task_mutex);
872 g_main_loop_run (loop);
876 test_run_in_thread_priority (void)
879 GCancellable *cancellable;
880 int seq_a, seq_b, seq_c, seq_d;
882 clog_up_thread_pool ();
884 /* Queue three more tasks that we'll arrange to have run serially */
885 task = g_task_new (NULL, NULL, NULL, NULL);
886 g_task_set_task_data (task, &seq_a, NULL);
887 g_task_run_in_thread (task, set_sequence_number_thread);
888 g_object_unref (task);
890 task = g_task_new (NULL, NULL, quit_main_loop_callback, NULL);
891 g_task_set_task_data (task, &seq_b, NULL);
892 g_task_set_priority (task, G_PRIORITY_LOW);
893 g_task_run_in_thread (task, set_sequence_number_thread);
894 g_object_unref (task);
896 task = g_task_new (NULL, NULL, NULL, NULL);
897 g_task_set_task_data (task, &seq_c, NULL);
898 g_task_set_priority (task, G_PRIORITY_HIGH);
899 g_task_run_in_thread (task, set_sequence_number_thread);
900 g_object_unref (task);
902 cancellable = g_cancellable_new ();
903 task = g_task_new (NULL, cancellable, NULL, NULL);
904 g_task_set_task_data (task, &seq_d, NULL);
905 g_task_run_in_thread (task, set_sequence_number_thread);
906 g_cancellable_cancel (cancellable);
907 g_object_unref (cancellable);
908 g_object_unref (task);
910 /* Let the last fake task complete; the four other tasks will then
911 * complete serially, in the order D, C, A, B, and B will quit the
914 g_mutex_unlock (&last_fake_task_mutex);
915 g_main_loop_run (loop);
917 g_assert_cmpint (seq_d, ==, 1);
918 g_assert_cmpint (seq_c, ==, 2);
919 g_assert_cmpint (seq_a, ==, 3);
920 g_assert_cmpint (seq_b, ==, 4);
922 unclog_thread_pool ();
925 /* test_run_in_thread_nested: task threads that block waiting on
926 * other task threads will not cause the thread pool to starve.
930 run_nested_task_thread (GTask *task,
931 gpointer source_object,
933 GCancellable *cancellable)
936 int *nested_tasks_left = task_data;
938 if ((*nested_tasks_left)--)
940 nested = g_task_new (NULL, NULL, NULL, NULL);
941 g_task_set_task_data (nested, nested_tasks_left, NULL);
942 g_task_run_in_thread_sync (nested, run_nested_task_thread);
943 g_object_unref (nested);
946 g_task_return_boolean (task, TRUE);
950 test_run_in_thread_nested (void)
953 int nested_tasks_left = 2;
955 clog_up_thread_pool ();
957 task = g_task_new (NULL, NULL, quit_main_loop_callback, NULL);
958 g_task_set_task_data (task, &nested_tasks_left, NULL);
959 g_task_run_in_thread (task, run_nested_task_thread);
960 g_object_unref (task);
962 g_mutex_unlock (&last_fake_task_mutex);
963 g_main_loop_run (loop);
965 unclog_thread_pool ();
968 /* test_return_on_cancel */
970 GMutex roc_init_mutex, roc_finish_mutex;
971 GCond roc_init_cond, roc_finish_cond;
981 return_on_cancel_callback (GObject *object,
982 GAsyncResult *result,
985 gboolean *callback_ran = user_data;
986 GError *error = NULL;
989 g_assert (g_thread_self () == main_thread);
991 g_assert (object == NULL);
992 g_assert (g_task_is_valid (result, object));
993 g_assert (g_async_result_get_user_data (result) == user_data);
994 g_assert (g_task_had_error (G_TASK (result)));
996 ret = g_task_propagate_int (G_TASK (result), &error);
997 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
998 g_clear_error (&error);
999 g_assert_cmpint (ret, ==, -1);
1001 *callback_ran = TRUE;
1002 g_main_loop_quit (loop);
1006 return_on_cancel_thread (GTask *task,
1007 gpointer source_object,
1009 GCancellable *cancellable)
1011 ThreadState *state = task_data;
1013 g_assert (source_object == g_task_get_source_object (task));
1014 g_assert (task_data == g_task_get_task_data (task));
1015 g_assert (cancellable == g_task_get_cancellable (task));
1017 g_assert (g_thread_self () != main_thread);
1019 g_mutex_lock (&roc_init_mutex);
1020 *state = THREAD_RUNNING;
1021 g_cond_signal (&roc_init_cond);
1022 g_mutex_unlock (&roc_init_mutex);
1024 g_mutex_lock (&roc_finish_mutex);
1026 if (!g_task_get_return_on_cancel (task) ||
1027 g_task_set_return_on_cancel (task, FALSE))
1029 *state = THREAD_COMPLETED;
1030 g_task_return_int (task, magic);
1033 *state = THREAD_CANCELLED;
1035 g_cond_signal (&roc_finish_cond);
1036 g_mutex_unlock (&roc_finish_mutex);
1040 test_return_on_cancel (void)
1043 GCancellable *cancellable;
1044 volatile ThreadState thread_state;
1045 gboolean callback_ran;
1047 cancellable = g_cancellable_new ();
1049 /* If return-on-cancel is FALSE (default), the task does not return
1052 callback_ran = FALSE;
1053 thread_state = THREAD_STARTING;
1054 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1056 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1057 g_mutex_lock (&roc_init_mutex);
1058 g_mutex_lock (&roc_finish_mutex);
1059 g_task_run_in_thread (task, return_on_cancel_thread);
1060 g_object_unref (task);
1062 while (thread_state == THREAD_STARTING)
1063 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1064 g_mutex_unlock (&roc_init_mutex);
1066 g_assert (thread_state == THREAD_RUNNING);
1067 g_assert (callback_ran == FALSE);
1069 g_cancellable_cancel (cancellable);
1070 g_mutex_unlock (&roc_finish_mutex);
1071 g_main_loop_run (loop);
1073 g_assert (thread_state == THREAD_COMPLETED);
1074 g_assert (callback_ran == TRUE);
1076 g_cancellable_reset (cancellable);
1078 /* If return-on-cancel is TRUE, it does return early */
1079 callback_ran = FALSE;
1080 thread_state = THREAD_STARTING;
1081 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1082 g_task_set_return_on_cancel (task, TRUE);
1084 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1085 g_mutex_lock (&roc_init_mutex);
1086 g_mutex_lock (&roc_finish_mutex);
1087 g_task_run_in_thread (task, return_on_cancel_thread);
1088 g_object_unref (task);
1090 while (thread_state == THREAD_STARTING)
1091 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1092 g_mutex_unlock (&roc_init_mutex);
1094 g_assert (thread_state == THREAD_RUNNING);
1095 g_assert (callback_ran == FALSE);
1097 g_cancellable_cancel (cancellable);
1098 g_main_loop_run (loop);
1099 g_assert (thread_state == THREAD_RUNNING);
1100 g_assert (callback_ran == TRUE);
1102 while (thread_state == THREAD_RUNNING)
1103 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1104 g_mutex_unlock (&roc_finish_mutex);
1106 g_assert (thread_state == THREAD_CANCELLED);
1107 /* We can't g_assert (task == NULL) here because it won't become NULL
1108 * until a little bit after roc_finish_cond is signaled.
1111 g_cancellable_reset (cancellable);
1113 /* If the task is already cancelled before it starts, it returns
1114 * immediately, but the thread func still runs.
1116 callback_ran = FALSE;
1117 thread_state = THREAD_STARTING;
1118 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1119 g_task_set_return_on_cancel (task, TRUE);
1121 g_cancellable_cancel (cancellable);
1123 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1124 g_mutex_lock (&roc_init_mutex);
1125 g_mutex_lock (&roc_finish_mutex);
1126 g_task_run_in_thread (task, return_on_cancel_thread);
1127 g_object_unref (task);
1129 g_main_loop_run (loop);
1130 g_assert (callback_ran == TRUE);
1132 while (thread_state == THREAD_STARTING)
1133 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1134 g_mutex_unlock (&roc_init_mutex);
1136 g_assert (thread_state == THREAD_RUNNING);
1138 while (thread_state == THREAD_RUNNING)
1139 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1140 g_mutex_unlock (&roc_finish_mutex);
1142 g_assert (thread_state == THREAD_CANCELLED);
1144 g_object_unref (cancellable);
1147 /* test_return_on_cancel_sync */
1150 cancel_sync_runner_thread (gpointer task)
1152 g_task_run_in_thread_sync (task, return_on_cancel_thread);
1157 test_return_on_cancel_sync (void)
1160 GCancellable *cancellable;
1161 volatile ThreadState thread_state;
1162 GThread *runner_thread;
1164 GError *error = NULL;
1166 cancellable = g_cancellable_new ();
1168 /* If return-on-cancel is FALSE, the task does not return early.
1170 thread_state = THREAD_STARTING;
1171 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
1173 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1174 g_mutex_lock (&roc_init_mutex);
1175 g_mutex_lock (&roc_finish_mutex);
1176 runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
1177 cancel_sync_runner_thread, task);
1179 while (thread_state == THREAD_STARTING)
1180 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1181 g_mutex_unlock (&roc_init_mutex);
1183 g_assert (thread_state == THREAD_RUNNING);
1185 g_cancellable_cancel (cancellable);
1186 g_mutex_unlock (&roc_finish_mutex);
1187 g_thread_join (runner_thread);
1188 g_assert (thread_state == THREAD_COMPLETED);
1190 ret = g_task_propagate_int (task, &error);
1191 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1192 g_clear_error (&error);
1193 g_assert_cmpint (ret, ==, -1);
1195 g_object_unref (task);
1197 g_cancellable_reset (cancellable);
1199 /* If return-on-cancel is TRUE, it does return early */
1200 thread_state = THREAD_STARTING;
1201 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
1202 g_task_set_return_on_cancel (task, TRUE);
1204 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1205 g_mutex_lock (&roc_init_mutex);
1206 g_mutex_lock (&roc_finish_mutex);
1207 runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
1208 cancel_sync_runner_thread, task);
1210 while (thread_state == THREAD_STARTING)
1211 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1212 g_mutex_unlock (&roc_init_mutex);
1214 g_assert (thread_state == THREAD_RUNNING);
1216 g_cancellable_cancel (cancellable);
1217 g_thread_join (runner_thread);
1218 g_assert (thread_state == THREAD_RUNNING);
1220 ret = g_task_propagate_int (task, &error);
1221 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1222 g_clear_error (&error);
1223 g_assert_cmpint (ret, ==, -1);
1225 g_object_unref (task);
1227 while (thread_state == THREAD_RUNNING)
1228 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1229 g_mutex_unlock (&roc_finish_mutex);
1231 g_assert (thread_state == THREAD_CANCELLED);
1233 g_cancellable_reset (cancellable);
1235 /* If the task is already cancelled before it starts, it returns
1236 * immediately, but the thread func still runs.
1238 thread_state = THREAD_STARTING;
1239 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
1240 g_task_set_return_on_cancel (task, TRUE);
1242 g_cancellable_cancel (cancellable);
1244 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1245 g_mutex_lock (&roc_init_mutex);
1246 g_mutex_lock (&roc_finish_mutex);
1247 runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
1248 cancel_sync_runner_thread, task);
1250 g_thread_join (runner_thread);
1251 g_assert (thread_state == THREAD_STARTING);
1253 ret = g_task_propagate_int (task, &error);
1254 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1255 g_clear_error (&error);
1256 g_assert_cmpint (ret, ==, -1);
1258 g_object_unref (task);
1260 while (thread_state == THREAD_STARTING)
1261 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1262 g_mutex_unlock (&roc_init_mutex);
1264 g_assert (thread_state == THREAD_RUNNING);
1266 while (thread_state == THREAD_RUNNING)
1267 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1268 g_mutex_unlock (&roc_finish_mutex);
1270 g_assert (thread_state == THREAD_CANCELLED);
1272 g_object_unref (cancellable);
1275 /* test_return_on_cancel_atomic: turning return-on-cancel on/off is
1279 GMutex roca_mutex_1, roca_mutex_2;
1280 GCond roca_cond_1, roca_cond_2;
1283 return_on_cancel_atomic_callback (GObject *object,
1284 GAsyncResult *result,
1287 gboolean *callback_ran = user_data;
1288 GError *error = NULL;
1291 g_assert (g_thread_self () == main_thread);
1293 g_assert (object == NULL);
1294 g_assert (g_task_is_valid (result, object));
1295 g_assert (g_async_result_get_user_data (result) == user_data);
1296 g_assert (g_task_had_error (G_TASK (result)));
1298 ret = g_task_propagate_int (G_TASK (result), &error);
1299 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1300 g_clear_error (&error);
1301 g_assert_cmpint (ret, ==, -1);
1303 *callback_ran = TRUE;
1304 g_main_loop_quit (loop);
1308 idle_quit_loop (gpointer user_data)
1310 g_main_loop_quit (loop);
1315 return_on_cancel_atomic_thread (GTask *task,
1316 gpointer source_object,
1318 GCancellable *cancellable)
1320 gint *state = task_data;
1322 g_assert (source_object == g_task_get_source_object (task));
1323 g_assert (task_data == g_task_get_task_data (task));
1324 g_assert (cancellable == g_task_get_cancellable (task));
1326 g_assert (g_thread_self () != main_thread);
1327 g_assert_cmpint (*state, ==, 0);
1329 g_mutex_lock (&roca_mutex_1);
1331 g_cond_signal (&roca_cond_1);
1332 g_mutex_unlock (&roca_mutex_1);
1334 g_mutex_lock (&roca_mutex_2);
1335 if (g_task_set_return_on_cancel (task, FALSE))
1339 g_cond_signal (&roca_cond_2);
1340 g_mutex_unlock (&roca_mutex_2);
1342 g_mutex_lock (&roca_mutex_1);
1343 if (g_task_set_return_on_cancel (task, TRUE))
1347 g_cond_signal (&roca_cond_1);
1348 g_mutex_unlock (&roca_mutex_1);
1350 g_mutex_lock (&roca_mutex_2);
1351 if (g_task_set_return_on_cancel (task, TRUE))
1355 g_cond_signal (&roca_cond_2);
1356 g_mutex_unlock (&roca_mutex_2);
1358 g_task_return_int (task, magic);
1362 test_return_on_cancel_atomic (void)
1365 GCancellable *cancellable;
1366 volatile gint state;
1367 gboolean callback_ran;
1369 cancellable = g_cancellable_new ();
1370 g_mutex_lock (&roca_mutex_1);
1371 g_mutex_lock (&roca_mutex_2);
1373 /* If we don't cancel it, each set_return_on_cancel() call will succeed */
1375 callback_ran = FALSE;
1376 task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran);
1377 g_task_set_return_on_cancel (task, TRUE);
1379 g_task_set_task_data (task, (gpointer)&state, NULL);
1380 g_task_run_in_thread (task, return_on_cancel_atomic_thread);
1381 g_object_unref (task);
1383 g_assert_cmpint (state, ==, 0);
1386 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1387 g_assert (state == 1);
1390 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1391 g_assert (state == 2);
1394 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1395 g_assert (state == 4);
1398 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1399 g_assert (state == 6);
1401 /* callback assumes there'll be a cancelled error */
1402 g_cancellable_cancel (cancellable);
1404 g_assert (callback_ran == FALSE);
1405 g_main_loop_run (loop);
1406 g_assert (callback_ran == TRUE);
1408 g_cancellable_reset (cancellable);
1411 /* If we cancel while it's temporarily not return-on-cancel, the
1412 * task won't complete right away, and further
1413 * g_task_set_return_on_cancel() calls will return FALSE.
1416 callback_ran = FALSE;
1417 task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran);
1418 g_task_set_return_on_cancel (task, TRUE);
1420 g_task_set_task_data (task, (gpointer)&state, NULL);
1421 g_task_run_in_thread (task, return_on_cancel_atomic_thread);
1422 g_object_unref (task);
1424 g_assert_cmpint (state, ==, 0);
1427 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1428 g_assert (state == 1);
1429 g_assert (g_task_get_return_on_cancel (task));
1432 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1433 g_assert (state == 2);
1434 g_assert (!g_task_get_return_on_cancel (task));
1436 g_cancellable_cancel (cancellable);
1437 g_idle_add (idle_quit_loop, NULL);
1438 g_main_loop_run (loop);
1439 g_assert (callback_ran == FALSE);
1442 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1443 g_assert (state == 5);
1444 g_assert (!g_task_get_return_on_cancel (task));
1446 g_main_loop_run (loop);
1447 g_assert (callback_ran == TRUE);
1450 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1451 g_assert (state == 7);
1453 g_object_unref (cancellable);
1454 g_mutex_unlock (&roca_mutex_1);
1455 g_mutex_unlock (&roca_mutex_2);
1458 /* test_return_pointer: memory management of pointer returns */
1461 test_return_pointer (void)
1463 GObject *object, *ret;
1465 GCancellable *cancellable;
1466 GError *error = NULL;
1468 /* If we don't read back the return value, the task will
1469 * run its destroy notify.
1471 object = (GObject *)g_dummy_object_new ();
1472 g_assert_cmpint (object->ref_count, ==, 1);
1473 g_object_add_weak_pointer (object, (gpointer *)&object);
1475 task = g_task_new (NULL, NULL, NULL, NULL);
1476 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1477 g_task_return_pointer (task, object, g_object_unref);
1478 g_assert_cmpint (object->ref_count, ==, 1);
1480 g_object_unref (task);
1481 g_assert (task == NULL);
1482 g_assert (object == NULL);
1484 /* Likewise, if the return value is overwritten by an error */
1485 object = (GObject *)g_dummy_object_new ();
1486 g_assert_cmpint (object->ref_count, ==, 1);
1487 g_object_add_weak_pointer (object, (gpointer *)&object);
1489 cancellable = g_cancellable_new ();
1490 task = g_task_new (NULL, cancellable, NULL, NULL);
1491 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1492 g_task_return_pointer (task, object, g_object_unref);
1493 g_assert_cmpint (object->ref_count, ==, 1);
1494 g_cancellable_cancel (cancellable);
1495 g_assert_cmpint (object->ref_count, ==, 1);
1497 ret = g_task_propagate_pointer (task, &error);
1498 g_assert (ret == NULL);
1499 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1500 g_clear_error (&error);
1501 g_assert_cmpint (object->ref_count, ==, 1);
1503 g_object_unref (task);
1504 g_object_unref (cancellable);
1505 g_assert (task == NULL);
1506 g_assert (object == NULL);
1508 /* If we read back the return value, we steal its ref */
1509 object = (GObject *)g_dummy_object_new ();
1510 g_assert_cmpint (object->ref_count, ==, 1);
1511 g_object_add_weak_pointer (object, (gpointer *)&object);
1513 task = g_task_new (NULL, NULL, NULL, NULL);
1514 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1515 g_task_return_pointer (task, object, g_object_unref);
1516 g_assert_cmpint (object->ref_count, ==, 1);
1518 ret = g_task_propagate_pointer (task, &error);
1519 g_assert_no_error (error);
1520 g_assert (ret == object);
1521 g_assert_cmpint (object->ref_count, ==, 1);
1523 g_object_unref (task);
1524 g_assert (task == NULL);
1525 g_assert_cmpint (object->ref_count, ==, 1);
1526 g_object_unref (object);
1527 g_assert (object == NULL);
1530 /* test_object_keepalive: GTask takes a ref on its source object */
1532 static GObject *keepalive_object;
1535 keepalive_callback (GObject *object,
1536 GAsyncResult *result,
1539 gssize *result_out = user_data;
1540 GError *error = NULL;
1542 g_assert (object == keepalive_object);
1543 g_assert (g_task_is_valid (result, object));
1544 g_assert (g_async_result_get_user_data (result) == user_data);
1545 g_assert (!g_task_had_error (G_TASK (result)));
1547 *result_out = g_task_propagate_int (G_TASK (result), &error);
1548 g_assert_no_error (error);
1550 g_main_loop_quit (loop);
1554 test_object_keepalive (void)
1561 keepalive_object = object = (GObject *)g_dummy_object_new ();
1562 g_object_add_weak_pointer (object, (gpointer *)&object);
1564 task = g_task_new (object, NULL, keepalive_callback, &result);
1565 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1567 ref_count = object->ref_count;
1568 g_assert_cmpint (ref_count, >, 1);
1570 g_assert (g_task_get_source_object (task) == object);
1571 g_assert (g_async_result_get_source_object (G_ASYNC_RESULT (task)) == object);
1572 g_assert_cmpint (object->ref_count, ==, ref_count + 1);
1573 g_object_unref (object);
1575 g_object_unref (object);
1576 g_assert (object != NULL);
1578 g_task_return_int (task, magic);
1579 g_main_loop_run (loop);
1581 g_assert (object != NULL);
1582 g_assert_cmpint (result, ==, magic);
1584 g_object_unref (task);
1585 g_assert (task == NULL);
1586 g_assert (object == NULL);
1589 /* test_legacy_error: legacy GSimpleAsyncResult handling */
1590 static void test_legacy_error (void);
1593 legacy_error_callback (GObject *object,
1594 GAsyncResult *result,
1597 gssize *result_out = user_data;
1598 GError *error = NULL;
1600 g_assert (object == NULL);
1601 g_assert (g_async_result_is_tagged (result, test_legacy_error));
1602 g_assert (g_async_result_get_user_data (result) == user_data);
1604 if (g_async_result_legacy_propagate_error (result, &error))
1606 g_assert (!g_task_is_valid (result, object));
1607 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1608 g_assert (g_simple_async_result_is_valid (result, object, test_legacy_error));
1609 G_GNUC_END_IGNORE_DEPRECATIONS;
1611 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
1616 g_assert (g_task_is_valid (result, object));
1618 *result_out = g_task_propagate_int (G_TASK (result), NULL);
1619 /* Might be error, might not */
1622 g_main_loop_quit (loop);
1626 legacy_error_return (gpointer user_data)
1628 if (G_IS_TASK (user_data))
1630 GTask *task = user_data;
1632 g_task_return_int (task, magic);
1633 g_object_unref (task);
1637 GSimpleAsyncResult *simple = user_data;
1639 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1640 g_simple_async_result_set_error (simple,
1644 g_simple_async_result_complete (simple);
1645 G_GNUC_END_IGNORE_DEPRECATIONS;
1646 g_object_unref (simple);
1653 test_legacy_error (void)
1656 GSimpleAsyncResult *simple;
1660 task = g_task_new (NULL, NULL, legacy_error_callback, &result);
1661 g_task_set_source_tag (task, test_legacy_error);
1662 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1664 g_idle_add (legacy_error_return, task);
1665 g_main_loop_run (loop);
1667 g_assert_cmpint (result, ==, magic);
1668 g_assert (task == NULL);
1671 task = g_task_new (NULL, NULL, legacy_error_callback, &result);
1672 g_task_set_source_tag (task, test_legacy_error);
1673 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1675 g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
1677 g_object_unref (task);
1678 g_main_loop_run (loop);
1680 g_assert_cmpint (result, ==, -1);
1681 g_assert (task == NULL);
1683 /* GSimpleAsyncResult error */
1684 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1685 simple = g_simple_async_result_new (NULL, legacy_error_callback, &result,
1687 G_GNUC_END_IGNORE_DEPRECATIONS;
1688 g_object_add_weak_pointer (G_OBJECT (simple), (gpointer *)&simple);
1690 g_idle_add (legacy_error_return, simple);
1691 g_main_loop_run (loop);
1693 g_assert_cmpint (result, ==, -2);
1694 g_assert (simple == NULL);
1699 main (int argc, char **argv)
1703 g_test_init (&argc, &argv, NULL);
1705 loop = g_main_loop_new (NULL, FALSE);
1706 main_thread = g_thread_self ();
1707 magic = g_get_monotonic_time ();
1709 g_test_add_func ("/gtask/basic", test_basic);
1710 g_test_add_func ("/gtask/error", test_error);
1711 g_test_add_func ("/gtask/return-from-same-iteration", test_return_from_same_iteration);
1712 g_test_add_func ("/gtask/return-from-toplevel", test_return_from_toplevel);
1713 g_test_add_func ("/gtask/return-from-anon-thread", test_return_from_anon_thread);
1714 g_test_add_func ("/gtask/return-from-wrong-thread", test_return_from_wrong_thread);
1715 g_test_add_func ("/gtask/no-callback", test_no_callback);
1716 g_test_add_func ("/gtask/report-error", test_report_error);
1717 g_test_add_func ("/gtask/priority", test_priority);
1718 g_test_add_func ("/gtask/check-cancellable", test_check_cancellable);
1719 g_test_add_func ("/gtask/return-if-cancelled", test_return_if_cancelled);
1720 g_test_add_func ("/gtask/run-in-thread", test_run_in_thread);
1721 g_test_add_func ("/gtask/run-in-thread-sync", test_run_in_thread_sync);
1722 g_test_add_func ("/gtask/run-in-thread-priority", test_run_in_thread_priority);
1723 g_test_add_func ("/gtask/run-in-thread-nested", test_run_in_thread_nested);
1724 g_test_add_func ("/gtask/return-on-cancel", test_return_on_cancel);
1725 g_test_add_func ("/gtask/return-on-cancel-sync", test_return_on_cancel_sync);
1726 g_test_add_func ("/gtask/return-on-cancel-atomic", test_return_on_cancel_atomic);
1727 g_test_add_func ("/gtask/return-pointer", test_return_pointer);
1728 g_test_add_func ("/gtask/object-keepalive", test_object_keepalive);
1729 g_test_add_func ("/gtask/legacy-error", test_legacy_error);
1733 g_main_loop_unref (loop);