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 */
654 static GMutex run_in_thread_mutex;
655 static GCond run_in_thread_cond;
658 task_weak_notify (gpointer user_data,
661 gboolean *weak_notify_ran = user_data;
663 g_mutex_lock (&run_in_thread_mutex);
664 *weak_notify_ran = TRUE;
665 g_cond_signal (&run_in_thread_cond);
666 g_mutex_unlock (&run_in_thread_mutex);
670 run_in_thread_callback (GObject *object,
671 GAsyncResult *result,
674 gboolean *done = user_data;
675 GError *error = NULL;
678 g_assert (g_thread_self () == main_thread);
680 g_assert (object == NULL);
681 g_assert (g_task_is_valid (result, object));
682 g_assert (g_async_result_get_user_data (result) == user_data);
683 g_assert (!g_task_had_error (G_TASK (result)));
685 ret = g_task_propagate_int (G_TASK (result), &error);
686 g_assert_no_error (error);
687 g_assert_cmpint (ret, ==, magic);
690 g_main_loop_quit (loop);
694 run_in_thread_thread (GTask *task,
695 gpointer source_object,
697 GCancellable *cancellable)
699 gboolean *thread_ran = task_data;
701 g_assert (source_object == g_task_get_source_object (task));
702 g_assert (task_data == g_task_get_task_data (task));
703 g_assert (cancellable == g_task_get_cancellable (task));
705 g_assert (g_thread_self () != main_thread);
707 g_mutex_lock (&run_in_thread_mutex);
709 g_cond_signal (&run_in_thread_cond);
710 g_mutex_unlock (&run_in_thread_mutex);
712 g_task_return_int (task, magic);
716 test_run_in_thread (void)
719 volatile gboolean thread_ran = FALSE;
720 volatile gboolean weak_notify_ran = FALSE;
721 gboolean done = FALSE;
723 task = g_task_new (NULL, NULL, run_in_thread_callback, &done);
724 g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran);
726 g_task_set_task_data (task, (gpointer)&thread_ran, NULL);
727 g_task_run_in_thread (task, run_in_thread_thread);
728 g_object_unref (task);
730 g_mutex_lock (&run_in_thread_mutex);
732 g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
733 g_mutex_unlock (&run_in_thread_mutex);
735 g_assert (done == FALSE);
736 g_assert (weak_notify_ran == FALSE);
738 g_main_loop_run (loop);
740 g_assert (done == TRUE);
742 g_mutex_lock (&run_in_thread_mutex);
743 while (!weak_notify_ran)
744 g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
745 g_mutex_unlock (&run_in_thread_mutex);
748 /* test_run_in_thread_sync */
751 run_in_thread_sync_callback (GObject *object,
752 GAsyncResult *result,
755 /* g_task_run_in_thread_sync() does not invoke the task's callback */
756 g_assert_not_reached ();
760 run_in_thread_sync_thread (GTask *task,
761 gpointer source_object,
763 GCancellable *cancellable)
765 gboolean *thread_ran = task_data;
767 g_assert (source_object == g_task_get_source_object (task));
768 g_assert (task_data == g_task_get_task_data (task));
769 g_assert (cancellable == g_task_get_cancellable (task));
771 g_assert (g_thread_self () != main_thread);
774 g_task_return_int (task, magic);
778 test_run_in_thread_sync (void)
781 gboolean thread_ran = FALSE;
783 GError *error = NULL;
785 task = g_task_new (NULL, NULL, run_in_thread_sync_callback, NULL);
787 g_task_set_task_data (task, &thread_ran, NULL);
788 g_task_run_in_thread_sync (task, run_in_thread_sync_thread);
790 g_assert (thread_ran == TRUE);
791 g_assert (task != NULL);
792 g_assert (!g_task_had_error (task));
794 ret = g_task_propagate_int (task, &error);
795 g_assert_no_error (error);
796 g_assert_cmpint (ret, ==, magic);
798 g_object_unref (task);
801 /* test_run_in_thread_priority */
803 static GMutex fake_task_mutex, last_fake_task_mutex;
804 static gint sequence_number = 0;
807 quit_main_loop_callback (GObject *object,
808 GAsyncResult *result,
811 GError *error = NULL;
814 g_assert (g_thread_self () == main_thread);
816 g_assert (object == NULL);
817 g_assert (g_task_is_valid (result, object));
818 g_assert (g_async_result_get_user_data (result) == user_data);
819 g_assert (!g_task_had_error (G_TASK (result)));
821 ret = g_task_propagate_boolean (G_TASK (result), &error);
822 g_assert_no_error (error);
823 g_assert_cmpint (ret, ==, TRUE);
825 g_main_loop_quit (loop);
829 set_sequence_number_thread (GTask *task,
830 gpointer source_object,
832 GCancellable *cancellable)
834 gint *seq_no_p = task_data;
836 *seq_no_p = ++sequence_number;
837 g_task_return_boolean (task, TRUE);
841 fake_task_thread (GTask *task,
842 gpointer source_object,
844 GCancellable *cancellable)
846 GMutex *mutex = task_data;
848 g_mutex_lock (mutex);
849 g_mutex_unlock (mutex);
850 g_task_return_boolean (task, TRUE);
853 #define G_TASK_THREAD_POOL_SIZE 10
854 static int fake_tasks_running;
857 fake_task_callback (GObject *source,
858 GAsyncResult *result,
861 if (--fake_tasks_running == 0)
862 g_main_loop_quit (loop);
866 clog_up_thread_pool (void)
871 g_thread_pool_stop_unused_threads ();
873 g_mutex_lock (&fake_task_mutex);
874 for (i = 0; i < G_TASK_THREAD_POOL_SIZE - 1; i++)
876 task = g_task_new (NULL, NULL, fake_task_callback, NULL);
877 g_task_set_task_data (task, &fake_task_mutex, NULL);
878 g_assert_cmpint (g_task_get_priority (task), ==, G_PRIORITY_DEFAULT);
879 g_task_set_priority (task, G_PRIORITY_HIGH * 2);
880 g_assert_cmpint (g_task_get_priority (task), ==, G_PRIORITY_HIGH * 2);
881 g_task_run_in_thread (task, fake_task_thread);
882 g_object_unref (task);
883 fake_tasks_running++;
886 g_mutex_lock (&last_fake_task_mutex);
887 task = g_task_new (NULL, NULL, NULL, NULL);
888 g_task_set_task_data (task, &last_fake_task_mutex, NULL);
889 g_task_set_priority (task, G_PRIORITY_HIGH * 2);
890 g_task_run_in_thread (task, fake_task_thread);
891 g_object_unref (task);
895 unclog_thread_pool (void)
897 g_mutex_unlock (&fake_task_mutex);
898 g_main_loop_run (loop);
902 test_run_in_thread_priority (void)
905 GCancellable *cancellable;
906 int seq_a, seq_b, seq_c, seq_d;
908 clog_up_thread_pool ();
910 /* Queue three more tasks that we'll arrange to have run serially */
911 task = g_task_new (NULL, NULL, NULL, NULL);
912 g_task_set_task_data (task, &seq_a, NULL);
913 g_task_run_in_thread (task, set_sequence_number_thread);
914 g_object_unref (task);
916 task = g_task_new (NULL, NULL, quit_main_loop_callback, NULL);
917 g_task_set_task_data (task, &seq_b, NULL);
918 g_task_set_priority (task, G_PRIORITY_LOW);
919 g_task_run_in_thread (task, set_sequence_number_thread);
920 g_object_unref (task);
922 task = g_task_new (NULL, NULL, NULL, NULL);
923 g_task_set_task_data (task, &seq_c, NULL);
924 g_task_set_priority (task, G_PRIORITY_HIGH);
925 g_task_run_in_thread (task, set_sequence_number_thread);
926 g_object_unref (task);
928 cancellable = g_cancellable_new ();
929 task = g_task_new (NULL, cancellable, NULL, NULL);
930 g_task_set_task_data (task, &seq_d, NULL);
931 g_task_run_in_thread (task, set_sequence_number_thread);
932 g_cancellable_cancel (cancellable);
933 g_object_unref (cancellable);
934 g_object_unref (task);
936 /* Let the last fake task complete; the four other tasks will then
937 * complete serially, in the order D, C, A, B, and B will quit the
940 g_mutex_unlock (&last_fake_task_mutex);
941 g_main_loop_run (loop);
943 g_assert_cmpint (seq_d, ==, 1);
944 g_assert_cmpint (seq_c, ==, 2);
945 g_assert_cmpint (seq_a, ==, 3);
946 g_assert_cmpint (seq_b, ==, 4);
948 unclog_thread_pool ();
951 /* test_run_in_thread_nested: task threads that block waiting on
952 * other task threads will not cause the thread pool to starve.
956 run_nested_task_thread (GTask *task,
957 gpointer source_object,
959 GCancellable *cancellable)
962 int *nested_tasks_left = task_data;
964 if ((*nested_tasks_left)--)
966 nested = g_task_new (NULL, NULL, NULL, NULL);
967 g_task_set_task_data (nested, nested_tasks_left, NULL);
968 g_task_run_in_thread_sync (nested, run_nested_task_thread);
969 g_object_unref (nested);
972 g_task_return_boolean (task, TRUE);
976 test_run_in_thread_nested (void)
979 int nested_tasks_left = 2;
981 clog_up_thread_pool ();
983 task = g_task_new (NULL, NULL, quit_main_loop_callback, NULL);
984 g_task_set_task_data (task, &nested_tasks_left, NULL);
985 g_task_run_in_thread (task, run_nested_task_thread);
986 g_object_unref (task);
988 g_mutex_unlock (&last_fake_task_mutex);
989 g_main_loop_run (loop);
991 unclog_thread_pool ();
994 /* test_return_on_cancel */
996 GMutex roc_init_mutex, roc_finish_mutex;
997 GCond roc_init_cond, roc_finish_cond;
1007 return_on_cancel_callback (GObject *object,
1008 GAsyncResult *result,
1011 gboolean *callback_ran = user_data;
1012 GError *error = NULL;
1015 g_assert (g_thread_self () == main_thread);
1017 g_assert (object == NULL);
1018 g_assert (g_task_is_valid (result, object));
1019 g_assert (g_async_result_get_user_data (result) == user_data);
1020 g_assert (g_task_had_error (G_TASK (result)));
1022 ret = g_task_propagate_int (G_TASK (result), &error);
1023 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1024 g_clear_error (&error);
1025 g_assert_cmpint (ret, ==, -1);
1027 *callback_ran = TRUE;
1028 g_main_loop_quit (loop);
1032 return_on_cancel_thread (GTask *task,
1033 gpointer source_object,
1035 GCancellable *cancellable)
1037 ThreadState *state = task_data;
1039 g_assert (source_object == g_task_get_source_object (task));
1040 g_assert (task_data == g_task_get_task_data (task));
1041 g_assert (cancellable == g_task_get_cancellable (task));
1043 g_assert (g_thread_self () != main_thread);
1045 g_mutex_lock (&roc_init_mutex);
1046 *state = THREAD_RUNNING;
1047 g_cond_signal (&roc_init_cond);
1048 g_mutex_unlock (&roc_init_mutex);
1050 g_mutex_lock (&roc_finish_mutex);
1052 if (!g_task_get_return_on_cancel (task) ||
1053 g_task_set_return_on_cancel (task, FALSE))
1055 *state = THREAD_COMPLETED;
1056 g_task_return_int (task, magic);
1059 *state = THREAD_CANCELLED;
1061 g_cond_signal (&roc_finish_cond);
1062 g_mutex_unlock (&roc_finish_mutex);
1066 test_return_on_cancel (void)
1069 GCancellable *cancellable;
1070 volatile ThreadState thread_state;
1071 volatile gboolean weak_notify_ran = FALSE;
1072 gboolean callback_ran;
1074 cancellable = g_cancellable_new ();
1076 /* If return-on-cancel is FALSE (default), the task does not return
1079 callback_ran = FALSE;
1080 thread_state = THREAD_STARTING;
1081 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1083 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1084 g_mutex_lock (&roc_init_mutex);
1085 g_mutex_lock (&roc_finish_mutex);
1086 g_task_run_in_thread (task, return_on_cancel_thread);
1087 g_object_unref (task);
1089 while (thread_state == THREAD_STARTING)
1090 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1091 g_mutex_unlock (&roc_init_mutex);
1093 g_assert (thread_state == THREAD_RUNNING);
1094 g_assert (callback_ran == FALSE);
1096 g_cancellable_cancel (cancellable);
1097 g_mutex_unlock (&roc_finish_mutex);
1098 g_main_loop_run (loop);
1100 g_assert (thread_state == THREAD_COMPLETED);
1101 g_assert (callback_ran == TRUE);
1103 g_cancellable_reset (cancellable);
1105 /* If return-on-cancel is TRUE, it does return early */
1106 callback_ran = FALSE;
1107 thread_state = THREAD_STARTING;
1108 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1109 g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran);
1110 g_task_set_return_on_cancel (task, TRUE);
1112 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1113 g_mutex_lock (&roc_init_mutex);
1114 g_mutex_lock (&roc_finish_mutex);
1115 g_task_run_in_thread (task, return_on_cancel_thread);
1116 g_object_unref (task);
1118 while (thread_state == THREAD_STARTING)
1119 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1120 g_mutex_unlock (&roc_init_mutex);
1122 g_assert (thread_state == THREAD_RUNNING);
1123 g_assert (callback_ran == FALSE);
1125 g_cancellable_cancel (cancellable);
1126 g_main_loop_run (loop);
1127 g_assert (thread_state == THREAD_RUNNING);
1128 g_assert (callback_ran == TRUE);
1130 g_assert (weak_notify_ran == FALSE);
1132 while (thread_state == THREAD_RUNNING)
1133 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1134 g_mutex_unlock (&roc_finish_mutex);
1136 g_assert (thread_state == THREAD_CANCELLED);
1137 g_mutex_lock (&run_in_thread_mutex);
1138 while (!weak_notify_ran)
1139 g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex);
1140 g_mutex_unlock (&run_in_thread_mutex);
1142 g_cancellable_reset (cancellable);
1144 /* If the task is already cancelled before it starts, it returns
1145 * immediately, but the thread func still runs.
1147 callback_ran = FALSE;
1148 thread_state = THREAD_STARTING;
1149 task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran);
1150 g_task_set_return_on_cancel (task, TRUE);
1152 g_cancellable_cancel (cancellable);
1154 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1155 g_mutex_lock (&roc_init_mutex);
1156 g_mutex_lock (&roc_finish_mutex);
1157 g_task_run_in_thread (task, return_on_cancel_thread);
1158 g_object_unref (task);
1160 g_main_loop_run (loop);
1161 g_assert (callback_ran == TRUE);
1163 while (thread_state == THREAD_STARTING)
1164 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1165 g_mutex_unlock (&roc_init_mutex);
1167 g_assert (thread_state == THREAD_RUNNING);
1169 while (thread_state == THREAD_RUNNING)
1170 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1171 g_mutex_unlock (&roc_finish_mutex);
1173 g_assert (thread_state == THREAD_CANCELLED);
1175 g_object_unref (cancellable);
1178 /* test_return_on_cancel_sync */
1181 cancel_sync_runner_thread (gpointer task)
1183 g_task_run_in_thread_sync (task, return_on_cancel_thread);
1188 test_return_on_cancel_sync (void)
1191 GCancellable *cancellable;
1192 volatile ThreadState thread_state;
1193 GThread *runner_thread;
1195 GError *error = NULL;
1197 cancellable = g_cancellable_new ();
1199 /* If return-on-cancel is FALSE, the task does not return early.
1201 thread_state = THREAD_STARTING;
1202 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
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_mutex_unlock (&roc_finish_mutex);
1218 g_thread_join (runner_thread);
1219 g_assert (thread_state == THREAD_COMPLETED);
1221 ret = g_task_propagate_int (task, &error);
1222 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1223 g_clear_error (&error);
1224 g_assert_cmpint (ret, ==, -1);
1226 g_object_unref (task);
1228 g_cancellable_reset (cancellable);
1230 /* If return-on-cancel is TRUE, it does return early */
1231 thread_state = THREAD_STARTING;
1232 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
1233 g_task_set_return_on_cancel (task, TRUE);
1235 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1236 g_mutex_lock (&roc_init_mutex);
1237 g_mutex_lock (&roc_finish_mutex);
1238 runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
1239 cancel_sync_runner_thread, task);
1241 while (thread_state == THREAD_STARTING)
1242 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1243 g_mutex_unlock (&roc_init_mutex);
1245 g_assert (thread_state == THREAD_RUNNING);
1247 g_cancellable_cancel (cancellable);
1248 g_thread_join (runner_thread);
1249 g_assert (thread_state == THREAD_RUNNING);
1251 ret = g_task_propagate_int (task, &error);
1252 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1253 g_clear_error (&error);
1254 g_assert_cmpint (ret, ==, -1);
1256 g_object_unref (task);
1258 while (thread_state == THREAD_RUNNING)
1259 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1260 g_mutex_unlock (&roc_finish_mutex);
1262 g_assert (thread_state == THREAD_CANCELLED);
1264 g_cancellable_reset (cancellable);
1266 /* If the task is already cancelled before it starts, it returns
1267 * immediately, but the thread func still runs.
1269 thread_state = THREAD_STARTING;
1270 task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL);
1271 g_task_set_return_on_cancel (task, TRUE);
1273 g_cancellable_cancel (cancellable);
1275 g_task_set_task_data (task, (gpointer)&thread_state, NULL);
1276 g_mutex_lock (&roc_init_mutex);
1277 g_mutex_lock (&roc_finish_mutex);
1278 runner_thread = g_thread_new ("return-on-cancel-sync runner thread",
1279 cancel_sync_runner_thread, task);
1281 g_thread_join (runner_thread);
1282 g_assert (thread_state == THREAD_STARTING);
1284 ret = g_task_propagate_int (task, &error);
1285 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1286 g_clear_error (&error);
1287 g_assert_cmpint (ret, ==, -1);
1289 g_object_unref (task);
1291 while (thread_state == THREAD_STARTING)
1292 g_cond_wait (&roc_init_cond, &roc_init_mutex);
1293 g_mutex_unlock (&roc_init_mutex);
1295 g_assert (thread_state == THREAD_RUNNING);
1297 while (thread_state == THREAD_RUNNING)
1298 g_cond_wait (&roc_finish_cond, &roc_finish_mutex);
1299 g_mutex_unlock (&roc_finish_mutex);
1301 g_assert (thread_state == THREAD_CANCELLED);
1303 g_object_unref (cancellable);
1306 /* test_return_on_cancel_atomic: turning return-on-cancel on/off is
1310 GMutex roca_mutex_1, roca_mutex_2;
1311 GCond roca_cond_1, roca_cond_2;
1314 return_on_cancel_atomic_callback (GObject *object,
1315 GAsyncResult *result,
1318 gboolean *callback_ran = user_data;
1319 GError *error = NULL;
1322 g_assert (g_thread_self () == main_thread);
1324 g_assert (object == NULL);
1325 g_assert (g_task_is_valid (result, object));
1326 g_assert (g_async_result_get_user_data (result) == user_data);
1327 g_assert (g_task_had_error (G_TASK (result)));
1329 ret = g_task_propagate_int (G_TASK (result), &error);
1330 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1331 g_clear_error (&error);
1332 g_assert_cmpint (ret, ==, -1);
1334 *callback_ran = TRUE;
1335 g_main_loop_quit (loop);
1339 idle_quit_loop (gpointer user_data)
1341 g_main_loop_quit (loop);
1346 return_on_cancel_atomic_thread (GTask *task,
1347 gpointer source_object,
1349 GCancellable *cancellable)
1351 gint *state = task_data;
1353 g_assert (source_object == g_task_get_source_object (task));
1354 g_assert (task_data == g_task_get_task_data (task));
1355 g_assert (cancellable == g_task_get_cancellable (task));
1357 g_assert (g_thread_self () != main_thread);
1358 g_assert_cmpint (*state, ==, 0);
1360 g_mutex_lock (&roca_mutex_1);
1362 g_cond_signal (&roca_cond_1);
1363 g_mutex_unlock (&roca_mutex_1);
1365 g_mutex_lock (&roca_mutex_2);
1366 if (g_task_set_return_on_cancel (task, FALSE))
1370 g_cond_signal (&roca_cond_2);
1371 g_mutex_unlock (&roca_mutex_2);
1373 g_mutex_lock (&roca_mutex_1);
1374 if (g_task_set_return_on_cancel (task, TRUE))
1378 g_cond_signal (&roca_cond_1);
1379 g_mutex_unlock (&roca_mutex_1);
1381 g_mutex_lock (&roca_mutex_2);
1382 if (g_task_set_return_on_cancel (task, TRUE))
1386 g_cond_signal (&roca_cond_2);
1387 g_mutex_unlock (&roca_mutex_2);
1389 g_task_return_int (task, magic);
1393 test_return_on_cancel_atomic (void)
1396 GCancellable *cancellable;
1397 volatile gint state;
1398 gboolean callback_ran;
1400 cancellable = g_cancellable_new ();
1401 g_mutex_lock (&roca_mutex_1);
1402 g_mutex_lock (&roca_mutex_2);
1404 /* If we don't cancel it, each set_return_on_cancel() call will succeed */
1406 callback_ran = FALSE;
1407 task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran);
1408 g_task_set_return_on_cancel (task, TRUE);
1410 g_task_set_task_data (task, (gpointer)&state, NULL);
1411 g_task_run_in_thread (task, return_on_cancel_atomic_thread);
1412 g_object_unref (task);
1414 g_assert_cmpint (state, ==, 0);
1417 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1418 g_assert (state == 1);
1421 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1422 g_assert (state == 2);
1425 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1426 g_assert (state == 4);
1429 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1430 g_assert (state == 6);
1432 /* callback assumes there'll be a cancelled error */
1433 g_cancellable_cancel (cancellable);
1435 g_assert (callback_ran == FALSE);
1436 g_main_loop_run (loop);
1437 g_assert (callback_ran == TRUE);
1439 g_cancellable_reset (cancellable);
1442 /* If we cancel while it's temporarily not return-on-cancel, the
1443 * task won't complete right away, and further
1444 * g_task_set_return_on_cancel() calls will return FALSE.
1447 callback_ran = FALSE;
1448 task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran);
1449 g_task_set_return_on_cancel (task, TRUE);
1451 g_task_set_task_data (task, (gpointer)&state, NULL);
1452 g_task_run_in_thread (task, return_on_cancel_atomic_thread);
1453 g_object_unref (task);
1455 g_assert_cmpint (state, ==, 0);
1458 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1459 g_assert (state == 1);
1460 g_assert (g_task_get_return_on_cancel (task));
1463 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1464 g_assert (state == 2);
1465 g_assert (!g_task_get_return_on_cancel (task));
1467 g_cancellable_cancel (cancellable);
1468 g_idle_add (idle_quit_loop, NULL);
1469 g_main_loop_run (loop);
1470 g_assert (callback_ran == FALSE);
1473 g_cond_wait (&roca_cond_1, &roca_mutex_1);
1474 g_assert (state == 5);
1475 g_assert (!g_task_get_return_on_cancel (task));
1477 g_main_loop_run (loop);
1478 g_assert (callback_ran == TRUE);
1481 g_cond_wait (&roca_cond_2, &roca_mutex_2);
1482 g_assert (state == 7);
1484 g_object_unref (cancellable);
1485 g_mutex_unlock (&roca_mutex_1);
1486 g_mutex_unlock (&roca_mutex_2);
1489 /* test_return_pointer: memory management of pointer returns */
1492 test_return_pointer (void)
1494 GObject *object, *ret;
1496 GCancellable *cancellable;
1497 GError *error = NULL;
1499 /* If we don't read back the return value, the task will
1500 * run its destroy notify.
1502 object = (GObject *)g_dummy_object_new ();
1503 g_assert_cmpint (object->ref_count, ==, 1);
1504 g_object_add_weak_pointer (object, (gpointer *)&object);
1506 task = g_task_new (NULL, NULL, NULL, NULL);
1507 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1508 g_task_return_pointer (task, object, g_object_unref);
1509 g_assert_cmpint (object->ref_count, ==, 1);
1511 g_object_unref (task);
1512 g_assert (task == NULL);
1513 g_assert (object == NULL);
1515 /* Likewise, if the return value is overwritten by an error */
1516 object = (GObject *)g_dummy_object_new ();
1517 g_assert_cmpint (object->ref_count, ==, 1);
1518 g_object_add_weak_pointer (object, (gpointer *)&object);
1520 cancellable = g_cancellable_new ();
1521 task = g_task_new (NULL, cancellable, NULL, NULL);
1522 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1523 g_task_return_pointer (task, object, g_object_unref);
1524 g_assert_cmpint (object->ref_count, ==, 1);
1525 g_cancellable_cancel (cancellable);
1526 g_assert_cmpint (object->ref_count, ==, 1);
1528 ret = g_task_propagate_pointer (task, &error);
1529 g_assert (ret == NULL);
1530 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1531 g_clear_error (&error);
1532 g_assert_cmpint (object->ref_count, ==, 1);
1534 g_object_unref (task);
1535 g_object_unref (cancellable);
1536 g_assert (task == NULL);
1537 g_assert (object == NULL);
1539 /* If we read back the return value, we steal its ref */
1540 object = (GObject *)g_dummy_object_new ();
1541 g_assert_cmpint (object->ref_count, ==, 1);
1542 g_object_add_weak_pointer (object, (gpointer *)&object);
1544 task = g_task_new (NULL, NULL, NULL, NULL);
1545 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1546 g_task_return_pointer (task, object, g_object_unref);
1547 g_assert_cmpint (object->ref_count, ==, 1);
1549 ret = g_task_propagate_pointer (task, &error);
1550 g_assert_no_error (error);
1551 g_assert (ret == object);
1552 g_assert_cmpint (object->ref_count, ==, 1);
1554 g_object_unref (task);
1555 g_assert (task == NULL);
1556 g_assert_cmpint (object->ref_count, ==, 1);
1557 g_object_unref (object);
1558 g_assert (object == NULL);
1561 /* test_object_keepalive: GTask takes a ref on its source object */
1563 static GObject *keepalive_object;
1566 keepalive_callback (GObject *object,
1567 GAsyncResult *result,
1570 gssize *result_out = user_data;
1571 GError *error = NULL;
1573 g_assert (object == keepalive_object);
1574 g_assert (g_task_is_valid (result, object));
1575 g_assert (g_async_result_get_user_data (result) == user_data);
1576 g_assert (!g_task_had_error (G_TASK (result)));
1578 *result_out = g_task_propagate_int (G_TASK (result), &error);
1579 g_assert_no_error (error);
1581 g_main_loop_quit (loop);
1585 test_object_keepalive (void)
1592 keepalive_object = object = (GObject *)g_dummy_object_new ();
1593 g_object_add_weak_pointer (object, (gpointer *)&object);
1595 task = g_task_new (object, NULL, keepalive_callback, &result);
1596 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1598 ref_count = object->ref_count;
1599 g_assert_cmpint (ref_count, >, 1);
1601 g_assert (g_task_get_source_object (task) == object);
1602 g_assert (g_async_result_get_source_object (G_ASYNC_RESULT (task)) == object);
1603 g_assert_cmpint (object->ref_count, ==, ref_count + 1);
1604 g_object_unref (object);
1606 g_object_unref (object);
1607 g_assert (object != NULL);
1609 g_task_return_int (task, magic);
1610 g_main_loop_run (loop);
1612 g_assert (object != NULL);
1613 g_assert_cmpint (result, ==, magic);
1615 g_object_unref (task);
1616 g_assert (task == NULL);
1617 g_assert (object == NULL);
1620 /* test_legacy_error: legacy GSimpleAsyncResult handling */
1621 static void test_legacy_error (void);
1624 legacy_error_callback (GObject *object,
1625 GAsyncResult *result,
1628 gssize *result_out = user_data;
1629 GError *error = NULL;
1631 g_assert (object == NULL);
1632 g_assert (g_async_result_is_tagged (result, test_legacy_error));
1633 g_assert (g_async_result_get_user_data (result) == user_data);
1635 if (g_async_result_legacy_propagate_error (result, &error))
1637 g_assert (!g_task_is_valid (result, object));
1638 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1639 g_assert (g_simple_async_result_is_valid (result, object, test_legacy_error));
1640 G_GNUC_END_IGNORE_DEPRECATIONS;
1642 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
1647 g_assert (g_task_is_valid (result, object));
1649 *result_out = g_task_propagate_int (G_TASK (result), NULL);
1650 /* Might be error, might not */
1653 g_main_loop_quit (loop);
1657 legacy_error_return (gpointer user_data)
1659 if (G_IS_TASK (user_data))
1661 GTask *task = user_data;
1663 g_task_return_int (task, magic);
1664 g_object_unref (task);
1668 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
1670 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1671 g_simple_async_result_set_error (simple,
1675 g_simple_async_result_complete (simple);
1676 G_GNUC_END_IGNORE_DEPRECATIONS;
1677 g_object_unref (simple);
1684 test_legacy_error (void)
1687 GSimpleAsyncResult *simple;
1691 task = g_task_new (NULL, NULL, legacy_error_callback, &result);
1692 g_task_set_source_tag (task, test_legacy_error);
1693 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1695 g_idle_add (legacy_error_return, task);
1696 g_main_loop_run (loop);
1698 g_assert_cmpint (result, ==, magic);
1699 g_assert (task == NULL);
1702 task = g_task_new (NULL, NULL, legacy_error_callback, &result);
1703 g_task_set_source_tag (task, test_legacy_error);
1704 g_object_add_weak_pointer (G_OBJECT (task), (gpointer *)&task);
1706 g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
1708 g_object_unref (task);
1709 g_main_loop_run (loop);
1711 g_assert_cmpint (result, ==, -1);
1712 g_assert (task == NULL);
1714 /* GSimpleAsyncResult error */
1715 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1716 simple = g_simple_async_result_new (NULL, legacy_error_callback, &result,
1718 G_GNUC_END_IGNORE_DEPRECATIONS;
1719 g_object_add_weak_pointer (G_OBJECT (simple), (gpointer *)&simple);
1721 g_idle_add (legacy_error_return, simple);
1722 g_main_loop_run (loop);
1724 g_assert_cmpint (result, ==, -2);
1725 g_assert (simple == NULL);
1730 main (int argc, char **argv)
1734 g_test_init (&argc, &argv, NULL);
1736 loop = g_main_loop_new (NULL, FALSE);
1737 main_thread = g_thread_self ();
1738 magic = g_get_monotonic_time ();
1740 g_test_add_func ("/gtask/basic", test_basic);
1741 g_test_add_func ("/gtask/error", test_error);
1742 g_test_add_func ("/gtask/return-from-same-iteration", test_return_from_same_iteration);
1743 g_test_add_func ("/gtask/return-from-toplevel", test_return_from_toplevel);
1744 g_test_add_func ("/gtask/return-from-anon-thread", test_return_from_anon_thread);
1745 g_test_add_func ("/gtask/return-from-wrong-thread", test_return_from_wrong_thread);
1746 g_test_add_func ("/gtask/no-callback", test_no_callback);
1747 g_test_add_func ("/gtask/report-error", test_report_error);
1748 g_test_add_func ("/gtask/priority", test_priority);
1749 g_test_add_func ("/gtask/check-cancellable", test_check_cancellable);
1750 g_test_add_func ("/gtask/return-if-cancelled", test_return_if_cancelled);
1751 g_test_add_func ("/gtask/run-in-thread", test_run_in_thread);
1752 g_test_add_func ("/gtask/run-in-thread-sync", test_run_in_thread_sync);
1753 g_test_add_func ("/gtask/run-in-thread-priority", test_run_in_thread_priority);
1754 g_test_add_func ("/gtask/run-in-thread-nested", test_run_in_thread_nested);
1755 g_test_add_func ("/gtask/return-on-cancel", test_return_on_cancel);
1756 g_test_add_func ("/gtask/return-on-cancel-sync", test_return_on_cancel_sync);
1757 g_test_add_func ("/gtask/return-on-cancel-atomic", test_return_on_cancel_atomic);
1758 g_test_add_func ("/gtask/return-pointer", test_return_pointer);
1759 g_test_add_func ("/gtask/object-keepalive", test_object_keepalive);
1760 g_test_add_func ("/gtask/legacy-error", test_legacy_error);
1764 g_main_loop_unref (loop);