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.
15 static GMainLoop
*loop
;
16 static GThread
*main_thread
;
19 /* We need objects for a few tests where we don't care what type
20 * they are, just that they're GObjects.
22 #define g_dummy_object_new g_socket_client_new
25 idle_quit_loop (gpointer user_data
)
27 g_main_loop_quit (loop
);
32 completed_cb (GObject
*gobject
,
36 gboolean
*notification_emitted
= user_data
;
37 *notification_emitted
= TRUE
;
41 wait_for_completed_notification (GTask
*task
)
43 gboolean notification_emitted
= FALSE
;
44 gboolean is_completed
= FALSE
;
46 /* Hold a ref. so we can check the :completed property afterwards. */
49 g_signal_connect (task
, "notify::completed",
50 (GCallback
) completed_cb
, ¬ification_emitted
);
51 g_idle_add (idle_quit_loop
, NULL
);
52 g_main_loop_run (loop
);
53 g_assert_true (notification_emitted
);
55 g_assert_true (g_task_get_completed (task
));
56 g_object_get (G_OBJECT (task
), "completed", &is_completed
, NULL
);
57 g_assert_true (is_completed
);
59 g_object_unref (task
);
65 basic_callback (GObject
*object
,
69 gssize
*result_out
= user_data
;
72 g_assert (object
== NULL
);
73 g_assert (g_task_is_valid (result
, object
));
74 g_assert (g_async_result_get_user_data (result
) == user_data
);
75 g_assert (!g_task_had_error (G_TASK (result
)));
76 g_assert_false (g_task_get_completed (G_TASK (result
)));
78 *result_out
= g_task_propagate_int (G_TASK (result
), &error
);
79 g_assert_no_error (error
);
81 g_assert (!g_task_had_error (G_TASK (result
)));
83 g_main_loop_quit (loop
);
87 basic_return (gpointer user_data
)
89 GTask
*task
= user_data
;
91 g_task_return_int (task
, magic
);
92 g_object_unref (task
);
98 basic_destroy_notify (gpointer user_data
)
100 gboolean
*destroyed
= user_data
;
110 gboolean task_data_destroyed
= FALSE
;
111 gboolean notification_emitted
= FALSE
;
113 task
= g_task_new (NULL
, NULL
, basic_callback
, &result
);
114 g_task_set_task_data (task
, &task_data_destroyed
, basic_destroy_notify
);
115 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
116 g_signal_connect (task
, "notify::completed",
117 (GCallback
) completed_cb
, ¬ification_emitted
);
119 g_idle_add (basic_return
, task
);
120 g_main_loop_run (loop
);
122 g_assert_cmpint (result
, ==, magic
);
123 g_assert (task_data_destroyed
== TRUE
);
124 g_assert_true (notification_emitted
);
125 g_assert (task
== NULL
);
131 error_callback (GObject
*object
,
132 GAsyncResult
*result
,
135 gssize
*result_out
= user_data
;
136 GError
*error
= NULL
;
138 g_assert (object
== NULL
);
139 g_assert (g_task_is_valid (result
, object
));
140 g_assert (g_async_result_get_user_data (result
) == user_data
);
141 g_assert (g_task_had_error (G_TASK (result
)));
142 g_assert_false (g_task_get_completed (G_TASK (result
)));
144 *result_out
= g_task_propagate_int (G_TASK (result
), &error
);
145 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
);
146 g_error_free (error
);
148 g_assert (g_task_had_error (G_TASK (result
)));
150 g_main_loop_quit (loop
);
154 error_return (gpointer user_data
)
156 GTask
*task
= user_data
;
158 g_task_return_new_error (task
,
159 G_IO_ERROR
, G_IO_ERROR_FAILED
,
161 g_object_unref (task
);
167 error_destroy_notify (gpointer user_data
)
169 gboolean
*destroyed
= user_data
;
179 gboolean first_task_data_destroyed
= FALSE
;
180 gboolean second_task_data_destroyed
= FALSE
;
181 gboolean notification_emitted
= FALSE
;
183 task
= g_task_new (NULL
, NULL
, error_callback
, &result
);
184 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
185 g_signal_connect (task
, "notify::completed",
186 (GCallback
) completed_cb
, ¬ification_emitted
);
188 g_assert (first_task_data_destroyed
== FALSE
);
189 g_task_set_task_data (task
, &first_task_data_destroyed
, error_destroy_notify
);
190 g_assert (first_task_data_destroyed
== FALSE
);
192 /* Calling g_task_set_task_data() again will destroy the first data */
193 g_task_set_task_data (task
, &second_task_data_destroyed
, error_destroy_notify
);
194 g_assert (first_task_data_destroyed
== TRUE
);
195 g_assert (second_task_data_destroyed
== FALSE
);
197 g_idle_add (error_return
, task
);
198 g_main_loop_run (loop
);
200 g_assert_cmpint (result
, ==, -1);
201 g_assert (second_task_data_destroyed
== TRUE
);
202 g_assert_true (notification_emitted
);
203 g_assert (task
== NULL
);
206 /* test_return_from_same_iteration: calling g_task_return_* from the
207 * loop iteration the task was created in defers completion until the
210 gboolean same_result
= FALSE
;
211 gboolean same_notification_emitted
= FALSE
;
214 same_callback (GObject
*object
,
215 GAsyncResult
*result
,
218 gboolean
*result_out
= user_data
;
219 GError
*error
= NULL
;
221 g_assert (object
== NULL
);
222 g_assert (g_task_is_valid (result
, object
));
223 g_assert (g_async_result_get_user_data (result
) == user_data
);
224 g_assert (!g_task_had_error (G_TASK (result
)));
225 g_assert_false (g_task_get_completed (G_TASK (result
)));
227 *result_out
= g_task_propagate_boolean (G_TASK (result
), &error
);
228 g_assert_no_error (error
);
230 g_assert (!g_task_had_error (G_TASK (result
)));
232 g_main_loop_quit (loop
);
236 same_start (gpointer user_data
)
238 gpointer
*weak_pointer
= user_data
;
241 task
= g_task_new (NULL
, NULL
, same_callback
, &same_result
);
242 *weak_pointer
= task
;
243 g_object_add_weak_pointer (G_OBJECT (task
), weak_pointer
);
244 g_signal_connect (task
, "notify::completed",
245 (GCallback
) completed_cb
, &same_notification_emitted
);
247 g_task_return_boolean (task
, TRUE
);
248 g_object_unref (task
);
250 /* same_callback should not have been invoked yet */
251 g_assert (same_result
== FALSE
);
252 g_assert (*weak_pointer
== task
);
253 g_assert_false (same_notification_emitted
);
259 test_return_from_same_iteration (void)
261 gpointer weak_pointer
;
263 g_idle_add (same_start
, &weak_pointer
);
264 g_main_loop_run (loop
);
266 g_assert (same_result
== TRUE
);
267 g_assert (weak_pointer
== NULL
);
268 g_assert_true (same_notification_emitted
);
271 /* test_return_from_toplevel: calling g_task_return_* from outside any
272 * main loop completes the task inside the main loop.
274 gboolean toplevel_notification_emitted
= FALSE
;
277 toplevel_callback (GObject
*object
,
278 GAsyncResult
*result
,
281 gboolean
*result_out
= user_data
;
282 GError
*error
= NULL
;
284 g_assert (object
== NULL
);
285 g_assert (g_task_is_valid (result
, object
));
286 g_assert (g_async_result_get_user_data (result
) == user_data
);
287 g_assert (!g_task_had_error (G_TASK (result
)));
288 g_assert_false (g_task_get_completed (G_TASK (result
)));
290 *result_out
= g_task_propagate_boolean (G_TASK (result
), &error
);
291 g_assert_no_error (error
);
293 g_assert (!g_task_had_error (G_TASK (result
)));
295 g_main_loop_quit (loop
);
299 test_return_from_toplevel (void)
302 gboolean result
= FALSE
;
304 task
= g_task_new (NULL
, NULL
, toplevel_callback
, &result
);
305 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
306 g_signal_connect (task
, "notify::completed",
307 (GCallback
) completed_cb
, &toplevel_notification_emitted
);
309 g_task_return_boolean (task
, TRUE
);
310 g_object_unref (task
);
312 /* toplevel_callback should not have been invoked yet */
313 g_assert (result
== FALSE
);
314 g_assert (task
!= NULL
);
315 g_assert_false (toplevel_notification_emitted
);
317 g_main_loop_run (loop
);
319 g_assert (result
== TRUE
);
320 g_assert (task
== NULL
);
321 g_assert_true (toplevel_notification_emitted
);
324 /* test_return_from_anon_thread: calling g_task_return_* from a
325 * thread with no thread-default main context will complete the
326 * task in the task's context/thread.
329 gboolean anon_thread_notification_emitted
= FALSE
;
330 GThread
*anon_thread
;
333 anon_callback (GObject
*object
,
334 GAsyncResult
*result
,
337 gssize
*result_out
= user_data
;
338 GError
*error
= NULL
;
340 g_assert (object
== NULL
);
341 g_assert (g_task_is_valid (result
, object
));
342 g_assert (g_async_result_get_user_data (result
) == user_data
);
343 g_assert (!g_task_had_error (G_TASK (result
)));
344 g_assert_false (g_task_get_completed (G_TASK (result
)));
346 g_assert (g_thread_self () == main_thread
);
348 *result_out
= g_task_propagate_int (G_TASK (result
), &error
);
349 g_assert_no_error (error
);
351 g_assert (!g_task_had_error (G_TASK (result
)));
353 g_main_loop_quit (loop
);
357 anon_thread_func (gpointer user_data
)
359 GTask
*task
= user_data
;
361 g_task_return_int (task
, magic
);
362 g_object_unref (task
);
368 anon_start (gpointer user_data
)
370 GTask
*task
= user_data
;
372 anon_thread
= g_thread_new ("test_return_from_anon_thread",
373 anon_thread_func
, task
);
378 test_return_from_anon_thread (void)
383 task
= g_task_new (NULL
, NULL
, anon_callback
, &result
);
384 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
385 g_signal_connect (task
, "notify::completed",
386 (GCallback
) completed_cb
,
387 &anon_thread_notification_emitted
);
389 g_idle_add (anon_start
, task
);
390 g_main_loop_run (loop
);
392 g_thread_join (anon_thread
);
394 g_assert_cmpint (result
, ==, magic
);
395 g_assert (task
== NULL
);
396 g_assert_true (anon_thread_notification_emitted
);
399 /* test_return_from_wrong_thread: calling g_task_return_* from a
400 * thread with its own thread-default main context will complete the
401 * task in the task's context/thread.
404 gboolean wrong_thread_notification_emitted
= FALSE
;
405 GThread
*wrong_thread
;
408 wrong_callback (GObject
*object
,
409 GAsyncResult
*result
,
412 gssize
*result_out
= user_data
;
413 GError
*error
= NULL
;
415 g_assert (object
== NULL
);
416 g_assert (g_task_is_valid (result
, object
));
417 g_assert (g_async_result_get_user_data (result
) == user_data
);
418 g_assert (!g_task_had_error (G_TASK (result
)));
419 g_assert_false (g_task_get_completed (G_TASK (result
)));
421 g_assert (g_thread_self () == main_thread
);
423 *result_out
= g_task_propagate_int (G_TASK (result
), &error
);
424 g_assert_no_error (error
);
426 g_assert (!g_task_had_error (G_TASK (result
)));
428 g_main_loop_quit (loop
);
432 wrong_thread_func (gpointer user_data
)
434 GTask
*task
= user_data
;
435 GMainContext
*context
;
437 context
= g_main_context_new ();
438 g_main_context_push_thread_default (context
);
440 g_assert (g_task_get_context (task
) != context
);
442 g_task_return_int (task
, magic
);
443 g_object_unref (task
);
445 g_main_context_pop_thread_default (context
);
446 g_main_context_unref (context
);
452 wrong_start (gpointer user_data
)
454 GTask
*task
= user_data
;
456 wrong_thread
= g_thread_new ("test_return_from_anon_thread",
457 wrong_thread_func
, task
);
462 test_return_from_wrong_thread (void)
467 task
= g_task_new (NULL
, NULL
, wrong_callback
, &result
);
468 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
469 g_signal_connect (task
, "notify::completed",
470 (GCallback
) completed_cb
,
471 &wrong_thread_notification_emitted
);
473 g_idle_add (wrong_start
, task
);
474 g_main_loop_run (loop
);
476 g_thread_join (wrong_thread
);
478 g_assert_cmpint (result
, ==, magic
);
479 g_assert (task
== NULL
);
480 g_assert_true (wrong_thread_notification_emitted
);
483 /* test_no_callback */
486 test_no_callback (void)
490 task
= g_task_new (NULL
, NULL
, NULL
, NULL
);
491 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
493 g_task_return_boolean (task
, TRUE
);
494 g_object_unref (task
);
496 /* Even though there’s no callback, the :completed notification has to
497 * happen in an idle handler. */
498 g_assert_nonnull (task
);
499 wait_for_completed_notification (task
);
500 g_assert_null (task
);
503 /* test_report_error */
505 static void test_report_error (void);
506 gboolean error_notification_emitted
= FALSE
;
509 report_callback (GObject
*object
,
510 GAsyncResult
*result
,
513 gpointer
*weak_pointer
= user_data
;
514 GError
*error
= NULL
;
517 g_assert (object
== NULL
);
518 g_assert (g_task_is_valid (result
, object
));
519 g_assert (g_async_result_get_user_data (result
) == user_data
);
520 g_assert (g_async_result_is_tagged (result
, test_report_error
));
521 g_assert (g_task_get_source_tag (G_TASK (result
)) == test_report_error
);
522 g_assert (g_task_had_error (G_TASK (result
)));
523 g_assert_false (g_task_get_completed (G_TASK (result
)));
525 ret
= g_task_propagate_int (G_TASK (result
), &error
);
526 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
);
527 g_assert_cmpint (ret
, ==, -1);
528 g_error_free (error
);
530 g_assert (g_task_had_error (G_TASK (result
)));
532 *weak_pointer
= result
;
533 g_object_add_weak_pointer (G_OBJECT (result
), weak_pointer
);
534 g_signal_connect (result
, "notify::completed",
535 (GCallback
) completed_cb
, &error_notification_emitted
);
537 g_main_loop_quit (loop
);
541 test_report_error (void)
543 gpointer weak_pointer
= (gpointer
)-1;
545 g_task_report_new_error (NULL
, report_callback
, &weak_pointer
,
547 G_IO_ERROR
, G_IO_ERROR_FAILED
,
549 g_main_loop_run (loop
);
551 g_assert (weak_pointer
== NULL
);
552 g_assert_true (error_notification_emitted
);
555 /* test_priority: tasks complete in priority order */
557 static int counter
= 0;
560 priority_callback (GObject
*object
,
561 GAsyncResult
*result
,
564 gssize
*ret_out
= user_data
;
565 GError
*error
= NULL
;
567 g_assert (object
== NULL
);
568 g_assert (g_task_is_valid (result
, object
));
569 g_assert (g_async_result_get_user_data (result
) == user_data
);
570 g_assert (!g_task_had_error (G_TASK (result
)));
571 g_assert_false (g_task_get_completed (G_TASK (result
)));
573 g_task_propagate_boolean (G_TASK (result
), &error
);
574 g_assert_no_error (error
);
576 g_assert (!g_task_had_error (G_TASK (result
)));
578 *ret_out
= ++counter
;
581 g_main_loop_quit (loop
);
588 gssize ret1
, ret2
, ret3
;
590 /* t2 has higher priority than either t1 or t3, so we can't
591 * accidentally pass the test just by completing the tasks in the
592 * order they were created (or in reverse order).
595 t1
= g_task_new (NULL
, NULL
, priority_callback
, &ret1
);
596 g_task_set_priority (t1
, G_PRIORITY_DEFAULT
);
597 g_task_return_boolean (t1
, TRUE
);
600 t2
= g_task_new (NULL
, NULL
, priority_callback
, &ret2
);
601 g_task_set_priority (t2
, G_PRIORITY_HIGH
);
602 g_task_return_boolean (t2
, TRUE
);
605 t3
= g_task_new (NULL
, NULL
, priority_callback
, &ret3
);
606 g_task_set_priority (t3
, G_PRIORITY_LOW
);
607 g_task_return_boolean (t3
, TRUE
);
610 g_main_loop_run (loop
);
612 g_assert_cmpint (ret2
, ==, 1);
613 g_assert_cmpint (ret1
, ==, 2);
614 g_assert_cmpint (ret3
, ==, 3);
617 /* test_check_cancellable: cancellation overrides return value */
620 CANCEL_BEFORE
= (1 << 1),
621 CANCEL_AFTER
= (1 << 2),
622 CHECK_CANCELLABLE
= (1 << 3)
624 #define NUM_CANCEL_TESTS (CANCEL_BEFORE | CANCEL_AFTER | CHECK_CANCELLABLE)
627 cancel_callback (GObject
*object
,
628 GAsyncResult
*result
,
631 int state
= GPOINTER_TO_INT (user_data
);
633 GCancellable
*cancellable
;
634 GError
*error
= NULL
;
636 g_assert (object
== NULL
);
637 g_assert (g_task_is_valid (result
, object
));
638 g_assert (g_async_result_get_user_data (result
) == user_data
);
640 task
= G_TASK (result
);
641 cancellable
= g_task_get_cancellable (task
);
642 g_assert (G_IS_CANCELLABLE (cancellable
));
644 if (state
& (CANCEL_BEFORE
| CANCEL_AFTER
))
645 g_assert (g_cancellable_is_cancelled (cancellable
));
647 g_assert (!g_cancellable_is_cancelled (cancellable
));
649 if (state
& CHECK_CANCELLABLE
)
650 g_assert (g_task_get_check_cancellable (task
));
652 g_assert (!g_task_get_check_cancellable (task
));
654 if (g_task_propagate_boolean (task
, &error
))
656 g_assert (!g_cancellable_is_cancelled (cancellable
) ||
657 !g_task_get_check_cancellable (task
));
661 g_assert (g_cancellable_is_cancelled (cancellable
) &&
662 g_task_get_check_cancellable (task
));
663 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
664 g_error_free (error
);
667 g_main_loop_quit (loop
);
671 test_check_cancellable (void)
674 GCancellable
*cancellable
;
677 cancellable
= g_cancellable_new ();
679 for (state
= 0; state
<= NUM_CANCEL_TESTS
; state
++)
681 task
= g_task_new (NULL
, cancellable
, cancel_callback
,
682 GINT_TO_POINTER (state
));
683 g_task_set_check_cancellable (task
, (state
& CHECK_CANCELLABLE
) != 0);
685 if (state
& CANCEL_BEFORE
)
686 g_cancellable_cancel (cancellable
);
687 g_task_return_boolean (task
, TRUE
);
688 if (state
& CANCEL_AFTER
)
689 g_cancellable_cancel (cancellable
);
691 g_main_loop_run (loop
);
692 g_object_unref (task
);
693 g_cancellable_reset (cancellable
);
696 g_object_unref (cancellable
);
699 /* test_return_if_cancelled */
702 return_if_cancelled_callback (GObject
*object
,
703 GAsyncResult
*result
,
706 GError
*error
= NULL
;
708 g_assert (object
== NULL
);
709 g_assert (g_task_is_valid (result
, object
));
710 g_assert (g_async_result_get_user_data (result
) == user_data
);
711 g_assert (g_task_had_error (G_TASK (result
)));
712 g_assert_false (g_task_get_completed (G_TASK (result
)));
714 g_task_propagate_boolean (G_TASK (result
), &error
);
715 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
716 g_clear_error (&error
);
718 g_assert (g_task_had_error (G_TASK (result
)));
720 g_main_loop_quit (loop
);
724 test_return_if_cancelled (void)
727 GCancellable
*cancellable
;
729 gboolean notification_emitted
= FALSE
;
731 cancellable
= g_cancellable_new ();
733 task
= g_task_new (NULL
, cancellable
, return_if_cancelled_callback
, NULL
);
734 g_signal_connect (task
, "notify::completed",
735 (GCallback
) completed_cb
, ¬ification_emitted
);
737 g_cancellable_cancel (cancellable
);
738 cancelled
= g_task_return_error_if_cancelled (task
);
739 g_assert (cancelled
);
740 g_assert_false (notification_emitted
);
741 g_main_loop_run (loop
);
742 g_object_unref (task
);
743 g_assert_true (notification_emitted
);
744 g_cancellable_reset (cancellable
);
746 notification_emitted
= FALSE
;
748 task
= g_task_new (NULL
, cancellable
, return_if_cancelled_callback
, NULL
);
749 g_signal_connect (task
, "notify::completed",
750 (GCallback
) completed_cb
, ¬ification_emitted
);
752 g_task_set_check_cancellable (task
, FALSE
);
753 g_cancellable_cancel (cancellable
);
754 cancelled
= g_task_return_error_if_cancelled (task
);
755 g_assert (cancelled
);
756 g_assert_false (notification_emitted
);
757 g_main_loop_run (loop
);
758 g_object_unref (task
);
759 g_assert_true (notification_emitted
);
760 g_object_unref (cancellable
);
763 /* test_run_in_thread */
765 static GMutex run_in_thread_mutex
;
766 static GCond run_in_thread_cond
;
769 task_weak_notify (gpointer user_data
,
772 gboolean
*weak_notify_ran
= user_data
;
774 g_mutex_lock (&run_in_thread_mutex
);
775 *weak_notify_ran
= TRUE
;
776 g_cond_signal (&run_in_thread_cond
);
777 g_mutex_unlock (&run_in_thread_mutex
);
781 run_in_thread_callback (GObject
*object
,
782 GAsyncResult
*result
,
785 gboolean
*done
= user_data
;
786 GError
*error
= NULL
;
789 g_assert (g_thread_self () == main_thread
);
791 g_assert (object
== NULL
);
792 g_assert (g_task_is_valid (result
, object
));
793 g_assert (g_async_result_get_user_data (result
) == user_data
);
794 g_assert (!g_task_had_error (G_TASK (result
)));
795 g_assert_false (g_task_get_completed (G_TASK (result
)));
797 ret
= g_task_propagate_int (G_TASK (result
), &error
);
798 g_assert_no_error (error
);
799 g_assert_cmpint (ret
, ==, magic
);
801 g_assert (!g_task_had_error (G_TASK (result
)));
804 g_main_loop_quit (loop
);
808 run_in_thread_thread (GTask
*task
,
809 gpointer source_object
,
811 GCancellable
*cancellable
)
813 gboolean
*thread_ran
= task_data
;
815 g_assert (source_object
== g_task_get_source_object (task
));
816 g_assert (task_data
== g_task_get_task_data (task
));
817 g_assert (cancellable
== g_task_get_cancellable (task
));
818 g_assert_false (g_task_get_completed (task
));
820 g_assert (g_thread_self () != main_thread
);
822 g_mutex_lock (&run_in_thread_mutex
);
824 g_cond_signal (&run_in_thread_cond
);
825 g_mutex_unlock (&run_in_thread_mutex
);
827 g_task_return_int (task
, magic
);
831 test_run_in_thread (void)
834 volatile gboolean thread_ran
= FALSE
;
835 volatile gboolean weak_notify_ran
= FALSE
;
836 gboolean notification_emitted
= FALSE
;
837 gboolean done
= FALSE
;
839 task
= g_task_new (NULL
, NULL
, run_in_thread_callback
, &done
);
840 g_object_weak_ref (G_OBJECT (task
), task_weak_notify
, (gpointer
)&weak_notify_ran
);
841 g_signal_connect (task
, "notify::completed",
842 (GCallback
) completed_cb
, ¬ification_emitted
);
844 g_task_set_task_data (task
, (gpointer
)&thread_ran
, NULL
);
845 g_task_run_in_thread (task
, run_in_thread_thread
);
846 g_object_unref (task
);
848 g_mutex_lock (&run_in_thread_mutex
);
850 g_cond_wait (&run_in_thread_cond
, &run_in_thread_mutex
);
851 g_mutex_unlock (&run_in_thread_mutex
);
853 g_assert (done
== FALSE
);
854 g_assert (weak_notify_ran
== FALSE
);
856 g_main_loop_run (loop
);
858 g_assert (done
== TRUE
);
859 g_assert_true (notification_emitted
);
861 g_mutex_lock (&run_in_thread_mutex
);
862 while (!weak_notify_ran
)
863 g_cond_wait (&run_in_thread_cond
, &run_in_thread_mutex
);
864 g_mutex_unlock (&run_in_thread_mutex
);
867 /* test_run_in_thread_sync */
870 run_in_thread_sync_callback (GObject
*object
,
871 GAsyncResult
*result
,
874 /* g_task_run_in_thread_sync() does not invoke the task's callback */
875 g_assert_not_reached ();
879 run_in_thread_sync_thread (GTask
*task
,
880 gpointer source_object
,
882 GCancellable
*cancellable
)
884 gboolean
*thread_ran
= task_data
;
886 g_assert (source_object
== g_task_get_source_object (task
));
887 g_assert (task_data
== g_task_get_task_data (task
));
888 g_assert (cancellable
== g_task_get_cancellable (task
));
889 g_assert_false (g_task_get_completed (task
));
891 g_assert (g_thread_self () != main_thread
);
894 g_task_return_int (task
, magic
);
898 test_run_in_thread_sync (void)
901 gboolean thread_ran
= FALSE
;
903 gboolean notification_emitted
= FALSE
;
904 GError
*error
= NULL
;
906 task
= g_task_new (NULL
, NULL
, run_in_thread_sync_callback
, NULL
);
907 g_signal_connect (task
, "notify::completed",
908 (GCallback
) completed_cb
,
909 ¬ification_emitted
);
911 g_task_set_task_data (task
, &thread_ran
, NULL
);
912 g_task_run_in_thread_sync (task
, run_in_thread_sync_thread
);
914 g_assert (thread_ran
== TRUE
);
915 g_assert (task
!= NULL
);
916 g_assert (!g_task_had_error (task
));
917 g_assert_true (g_task_get_completed (task
));
918 g_assert_true (notification_emitted
);
920 ret
= g_task_propagate_int (task
, &error
);
921 g_assert_no_error (error
);
922 g_assert_cmpint (ret
, ==, magic
);
924 g_assert (!g_task_had_error (task
));
926 g_object_unref (task
);
929 /* test_run_in_thread_priority */
931 static GMutex fake_task_mutex
, last_fake_task_mutex
;
932 static gint sequence_number
= 0;
935 quit_main_loop_callback (GObject
*object
,
936 GAsyncResult
*result
,
939 GError
*error
= NULL
;
942 g_assert (g_thread_self () == main_thread
);
944 g_assert (object
== NULL
);
945 g_assert (g_task_is_valid (result
, object
));
946 g_assert (g_async_result_get_user_data (result
) == user_data
);
947 g_assert (!g_task_had_error (G_TASK (result
)));
948 g_assert_false (g_task_get_completed (G_TASK (result
)));
950 ret
= g_task_propagate_boolean (G_TASK (result
), &error
);
951 g_assert_no_error (error
);
952 g_assert_cmpint (ret
, ==, TRUE
);
954 g_assert (!g_task_had_error (G_TASK (result
)));
956 g_main_loop_quit (loop
);
960 set_sequence_number_thread (GTask
*task
,
961 gpointer source_object
,
963 GCancellable
*cancellable
)
965 gint
*seq_no_p
= task_data
;
967 *seq_no_p
= ++sequence_number
;
968 g_task_return_boolean (task
, TRUE
);
972 fake_task_thread (GTask
*task
,
973 gpointer source_object
,
975 GCancellable
*cancellable
)
977 GMutex
*mutex
= task_data
;
979 g_mutex_lock (mutex
);
980 g_mutex_unlock (mutex
);
981 g_task_return_boolean (task
, TRUE
);
984 #define G_TASK_THREAD_POOL_SIZE 10
985 static int fake_tasks_running
;
988 fake_task_callback (GObject
*source
,
989 GAsyncResult
*result
,
992 if (--fake_tasks_running
== 0)
993 g_main_loop_quit (loop
);
997 clog_up_thread_pool (void)
1002 g_thread_pool_stop_unused_threads ();
1004 g_mutex_lock (&fake_task_mutex
);
1005 for (i
= 0; i
< G_TASK_THREAD_POOL_SIZE
- 1; i
++)
1007 task
= g_task_new (NULL
, NULL
, fake_task_callback
, NULL
);
1008 g_task_set_task_data (task
, &fake_task_mutex
, NULL
);
1009 g_assert_cmpint (g_task_get_priority (task
), ==, G_PRIORITY_DEFAULT
);
1010 g_task_set_priority (task
, G_PRIORITY_HIGH
* 2);
1011 g_assert_cmpint (g_task_get_priority (task
), ==, G_PRIORITY_HIGH
* 2);
1012 g_task_run_in_thread (task
, fake_task_thread
);
1013 g_object_unref (task
);
1014 fake_tasks_running
++;
1017 g_mutex_lock (&last_fake_task_mutex
);
1018 task
= g_task_new (NULL
, NULL
, NULL
, NULL
);
1019 g_task_set_task_data (task
, &last_fake_task_mutex
, NULL
);
1020 g_task_set_priority (task
, G_PRIORITY_HIGH
* 2);
1021 g_task_run_in_thread (task
, fake_task_thread
);
1022 g_object_unref (task
);
1026 unclog_thread_pool (void)
1028 g_mutex_unlock (&fake_task_mutex
);
1029 g_main_loop_run (loop
);
1033 test_run_in_thread_priority (void)
1036 GCancellable
*cancellable
;
1037 int seq_a
, seq_b
, seq_c
, seq_d
;
1039 clog_up_thread_pool ();
1041 /* Queue three more tasks that we'll arrange to have run serially */
1042 task
= g_task_new (NULL
, NULL
, NULL
, NULL
);
1043 g_task_set_task_data (task
, &seq_a
, NULL
);
1044 g_task_run_in_thread (task
, set_sequence_number_thread
);
1045 g_object_unref (task
);
1047 task
= g_task_new (NULL
, NULL
, quit_main_loop_callback
, NULL
);
1048 g_task_set_task_data (task
, &seq_b
, NULL
);
1049 g_task_set_priority (task
, G_PRIORITY_LOW
);
1050 g_task_run_in_thread (task
, set_sequence_number_thread
);
1051 g_object_unref (task
);
1053 task
= g_task_new (NULL
, NULL
, NULL
, NULL
);
1054 g_task_set_task_data (task
, &seq_c
, NULL
);
1055 g_task_set_priority (task
, G_PRIORITY_HIGH
);
1056 g_task_run_in_thread (task
, set_sequence_number_thread
);
1057 g_object_unref (task
);
1059 cancellable
= g_cancellable_new ();
1060 task
= g_task_new (NULL
, cancellable
, NULL
, NULL
);
1061 g_task_set_task_data (task
, &seq_d
, NULL
);
1062 g_task_run_in_thread (task
, set_sequence_number_thread
);
1063 g_cancellable_cancel (cancellable
);
1064 g_object_unref (cancellable
);
1065 g_object_unref (task
);
1067 /* Let the last fake task complete; the four other tasks will then
1068 * complete serially, in the order D, C, A, B, and B will quit the
1071 g_mutex_unlock (&last_fake_task_mutex
);
1072 g_main_loop_run (loop
);
1074 g_assert_cmpint (seq_d
, ==, 1);
1075 g_assert_cmpint (seq_c
, ==, 2);
1076 g_assert_cmpint (seq_a
, ==, 3);
1077 g_assert_cmpint (seq_b
, ==, 4);
1079 unclog_thread_pool ();
1082 /* test_run_in_thread_nested: task threads that block waiting on
1083 * other task threads will not cause the thread pool to starve.
1087 run_nested_task_thread (GTask
*task
,
1088 gpointer source_object
,
1090 GCancellable
*cancellable
)
1093 int *nested_tasks_left
= task_data
;
1095 if ((*nested_tasks_left
)--)
1097 nested
= g_task_new (NULL
, NULL
, NULL
, NULL
);
1098 g_task_set_task_data (nested
, nested_tasks_left
, NULL
);
1099 g_task_run_in_thread_sync (nested
, run_nested_task_thread
);
1100 g_object_unref (nested
);
1103 g_task_return_boolean (task
, TRUE
);
1107 test_run_in_thread_nested (void)
1110 int nested_tasks_left
= 2;
1112 clog_up_thread_pool ();
1114 task
= g_task_new (NULL
, NULL
, quit_main_loop_callback
, NULL
);
1115 g_task_set_task_data (task
, &nested_tasks_left
, NULL
);
1116 g_task_run_in_thread (task
, run_nested_task_thread
);
1117 g_object_unref (task
);
1119 g_mutex_unlock (&last_fake_task_mutex
);
1120 g_main_loop_run (loop
);
1122 unclog_thread_pool ();
1125 /* test_run_in_thread_overflow: if you queue lots and lots and lots of
1126 * tasks, they won't all run at once.
1128 static GMutex overflow_mutex
;
1131 run_overflow_task_thread (GTask
*task
,
1132 gpointer source_object
,
1134 GCancellable
*cancellable
)
1136 gchar
*result
= task_data
;
1138 if (g_task_return_error_if_cancelled (task
))
1144 /* Block until the main thread is ready. */
1145 g_mutex_lock (&overflow_mutex
);
1146 g_mutex_unlock (&overflow_mutex
);
1150 g_task_return_boolean (task
, TRUE
);
1153 #define NUM_OVERFLOW_TASKS 1024
1156 test_run_in_thread_overflow (void)
1158 GCancellable
*cancellable
;
1160 gchar buf
[NUM_OVERFLOW_TASKS
+ 1];
1163 /* Queue way too many tasks and then sleep for a bit. The first 10
1164 * tasks will be dispatched to threads and will then block on
1165 * overflow_mutex, so more threads will be created while this thread
1166 * is sleeping. Then we cancel the cancellable, unlock the mutex,
1167 * wait for all of the tasks to complete, and make sure that we got
1168 * the behavior we expected.
1171 memset (buf
, 0, sizeof (buf
));
1172 cancellable
= g_cancellable_new ();
1174 g_mutex_lock (&overflow_mutex
);
1176 for (i
= 0; i
< NUM_OVERFLOW_TASKS
; i
++)
1178 task
= g_task_new (NULL
, cancellable
, NULL
, NULL
);
1179 g_task_set_task_data (task
, buf
+ i
, NULL
);
1180 g_task_run_in_thread (task
, run_overflow_task_thread
);
1181 g_object_unref (task
);
1185 g_usleep (5000000); /* 5 s */
1187 g_usleep (500000); /* 0.5 s */
1188 g_cancellable_cancel (cancellable
);
1189 g_object_unref (cancellable
);
1191 g_mutex_unlock (&overflow_mutex
);
1193 /* Wait for all tasks to complete. */
1194 while (strlen (buf
) != NUM_OVERFLOW_TASKS
)
1197 i
= strspn (buf
, ".");
1198 /* Given the sleep times above, i should be 14 for normal, 40 for
1199 * slow. But if the machine is too slow/busy then the scheduling
1200 * might get messed up and we'll get more or fewer threads than
1201 * expected. But there are limits to how messed up it could
1202 * plausibly get (and we hope that if gtask is actually broken then
1203 * it will exceed those limits).
1205 g_assert_cmpint (i
, >=, 10);
1207 g_assert_cmpint (i
, <, 50);
1209 g_assert_cmpint (i
, <, 20);
1211 g_assert_cmpint (i
+ strspn (buf
+ i
, "X"), ==, NUM_OVERFLOW_TASKS
);
1214 /* test_return_on_cancel */
1216 GMutex roc_init_mutex
, roc_finish_mutex
;
1217 GCond roc_init_cond
, roc_finish_cond
;
1227 return_on_cancel_callback (GObject
*object
,
1228 GAsyncResult
*result
,
1231 gboolean
*callback_ran
= user_data
;
1232 GError
*error
= NULL
;
1235 g_assert (g_thread_self () == main_thread
);
1237 g_assert (object
== NULL
);
1238 g_assert (g_task_is_valid (result
, object
));
1239 g_assert (g_async_result_get_user_data (result
) == user_data
);
1240 g_assert (g_task_had_error (G_TASK (result
)));
1241 g_assert_false (g_task_get_completed (G_TASK (result
)));
1243 ret
= g_task_propagate_int (G_TASK (result
), &error
);
1244 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
1245 g_clear_error (&error
);
1246 g_assert_cmpint (ret
, ==, -1);
1248 g_assert (g_task_had_error (G_TASK (result
)));
1250 *callback_ran
= TRUE
;
1251 g_main_loop_quit (loop
);
1255 return_on_cancel_thread (GTask
*task
,
1256 gpointer source_object
,
1258 GCancellable
*cancellable
)
1260 ThreadState
*state
= task_data
;
1262 g_assert (source_object
== g_task_get_source_object (task
));
1263 g_assert (task_data
== g_task_get_task_data (task
));
1264 g_assert (cancellable
== g_task_get_cancellable (task
));
1266 g_assert (g_thread_self () != main_thread
);
1268 g_mutex_lock (&roc_init_mutex
);
1269 *state
= THREAD_RUNNING
;
1270 g_cond_signal (&roc_init_cond
);
1271 g_mutex_unlock (&roc_init_mutex
);
1273 g_mutex_lock (&roc_finish_mutex
);
1275 if (!g_task_get_return_on_cancel (task
) ||
1276 g_task_set_return_on_cancel (task
, FALSE
))
1278 *state
= THREAD_COMPLETED
;
1279 g_task_return_int (task
, magic
);
1282 *state
= THREAD_CANCELLED
;
1284 g_cond_signal (&roc_finish_cond
);
1285 g_mutex_unlock (&roc_finish_mutex
);
1289 test_return_on_cancel (void)
1292 GCancellable
*cancellable
;
1293 volatile ThreadState thread_state
;
1294 volatile gboolean weak_notify_ran
= FALSE
;
1295 gboolean callback_ran
;
1296 gboolean notification_emitted
= FALSE
;
1298 cancellable
= g_cancellable_new ();
1300 /* If return-on-cancel is FALSE (default), the task does not return
1303 callback_ran
= FALSE
;
1304 thread_state
= THREAD_STARTING
;
1305 task
= g_task_new (NULL
, cancellable
, return_on_cancel_callback
, &callback_ran
);
1306 g_signal_connect (task
, "notify::completed",
1307 (GCallback
) completed_cb
, ¬ification_emitted
);
1309 g_task_set_task_data (task
, (gpointer
)&thread_state
, NULL
);
1310 g_mutex_lock (&roc_init_mutex
);
1311 g_mutex_lock (&roc_finish_mutex
);
1312 g_task_run_in_thread (task
, return_on_cancel_thread
);
1313 g_object_unref (task
);
1315 while (thread_state
== THREAD_STARTING
)
1316 g_cond_wait (&roc_init_cond
, &roc_init_mutex
);
1317 g_mutex_unlock (&roc_init_mutex
);
1319 g_assert (thread_state
== THREAD_RUNNING
);
1320 g_assert (callback_ran
== FALSE
);
1322 g_cancellable_cancel (cancellable
);
1323 g_mutex_unlock (&roc_finish_mutex
);
1324 g_main_loop_run (loop
);
1326 g_assert (thread_state
== THREAD_COMPLETED
);
1327 g_assert (callback_ran
== TRUE
);
1328 g_assert_true (notification_emitted
);
1330 g_cancellable_reset (cancellable
);
1332 /* If return-on-cancel is TRUE, it does return early */
1333 callback_ran
= FALSE
;
1334 notification_emitted
= FALSE
;
1335 thread_state
= THREAD_STARTING
;
1336 task
= g_task_new (NULL
, cancellable
, return_on_cancel_callback
, &callback_ran
);
1337 g_object_weak_ref (G_OBJECT (task
), task_weak_notify
, (gpointer
)&weak_notify_ran
);
1338 g_signal_connect (task
, "notify::completed",
1339 (GCallback
) completed_cb
, ¬ification_emitted
);
1340 g_task_set_return_on_cancel (task
, TRUE
);
1342 g_task_set_task_data (task
, (gpointer
)&thread_state
, NULL
);
1343 g_mutex_lock (&roc_init_mutex
);
1344 g_mutex_lock (&roc_finish_mutex
);
1345 g_task_run_in_thread (task
, return_on_cancel_thread
);
1346 g_object_unref (task
);
1348 while (thread_state
== THREAD_STARTING
)
1349 g_cond_wait (&roc_init_cond
, &roc_init_mutex
);
1350 g_mutex_unlock (&roc_init_mutex
);
1352 g_assert (thread_state
== THREAD_RUNNING
);
1353 g_assert (callback_ran
== FALSE
);
1355 g_cancellable_cancel (cancellable
);
1356 g_main_loop_run (loop
);
1357 g_assert (thread_state
== THREAD_RUNNING
);
1358 g_assert (callback_ran
== TRUE
);
1360 g_assert (weak_notify_ran
== FALSE
);
1362 while (thread_state
== THREAD_RUNNING
)
1363 g_cond_wait (&roc_finish_cond
, &roc_finish_mutex
);
1364 g_mutex_unlock (&roc_finish_mutex
);
1366 g_assert (thread_state
== THREAD_CANCELLED
);
1367 g_mutex_lock (&run_in_thread_mutex
);
1368 while (!weak_notify_ran
)
1369 g_cond_wait (&run_in_thread_cond
, &run_in_thread_mutex
);
1370 g_mutex_unlock (&run_in_thread_mutex
);
1372 g_assert_true (notification_emitted
);
1373 g_cancellable_reset (cancellable
);
1375 /* If the task is already cancelled before it starts, it returns
1376 * immediately, but the thread func still runs.
1378 callback_ran
= FALSE
;
1379 notification_emitted
= FALSE
;
1380 thread_state
= THREAD_STARTING
;
1381 task
= g_task_new (NULL
, cancellable
, return_on_cancel_callback
, &callback_ran
);
1382 g_signal_connect (task
, "notify::completed",
1383 (GCallback
) completed_cb
, ¬ification_emitted
);
1384 g_task_set_return_on_cancel (task
, TRUE
);
1386 g_cancellable_cancel (cancellable
);
1388 g_task_set_task_data (task
, (gpointer
)&thread_state
, NULL
);
1389 g_mutex_lock (&roc_init_mutex
);
1390 g_mutex_lock (&roc_finish_mutex
);
1391 g_task_run_in_thread (task
, return_on_cancel_thread
);
1392 g_object_unref (task
);
1394 g_main_loop_run (loop
);
1395 g_assert (callback_ran
== TRUE
);
1397 while (thread_state
== THREAD_STARTING
)
1398 g_cond_wait (&roc_init_cond
, &roc_init_mutex
);
1399 g_mutex_unlock (&roc_init_mutex
);
1401 g_assert (thread_state
== THREAD_RUNNING
);
1403 while (thread_state
== THREAD_RUNNING
)
1404 g_cond_wait (&roc_finish_cond
, &roc_finish_mutex
);
1405 g_mutex_unlock (&roc_finish_mutex
);
1407 g_assert (thread_state
== THREAD_CANCELLED
);
1408 g_assert_true (notification_emitted
);
1410 g_object_unref (cancellable
);
1413 /* test_return_on_cancel_sync */
1416 cancel_sync_runner_thread (gpointer task
)
1418 g_task_run_in_thread_sync (task
, return_on_cancel_thread
);
1423 test_return_on_cancel_sync (void)
1426 GCancellable
*cancellable
;
1427 volatile ThreadState thread_state
;
1428 GThread
*runner_thread
;
1430 GError
*error
= NULL
;
1432 cancellable
= g_cancellable_new ();
1434 /* If return-on-cancel is FALSE, the task does not return early.
1436 thread_state
= THREAD_STARTING
;
1437 task
= g_task_new (NULL
, cancellable
, run_in_thread_sync_callback
, NULL
);
1439 g_task_set_task_data (task
, (gpointer
)&thread_state
, NULL
);
1440 g_mutex_lock (&roc_init_mutex
);
1441 g_mutex_lock (&roc_finish_mutex
);
1442 runner_thread
= g_thread_new ("return-on-cancel-sync runner thread",
1443 cancel_sync_runner_thread
, task
);
1445 while (thread_state
== THREAD_STARTING
)
1446 g_cond_wait (&roc_init_cond
, &roc_init_mutex
);
1447 g_mutex_unlock (&roc_init_mutex
);
1449 g_assert (thread_state
== THREAD_RUNNING
);
1451 g_cancellable_cancel (cancellable
);
1452 g_mutex_unlock (&roc_finish_mutex
);
1453 g_thread_join (runner_thread
);
1454 g_assert (thread_state
== THREAD_COMPLETED
);
1456 ret
= g_task_propagate_int (task
, &error
);
1457 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
1458 g_clear_error (&error
);
1459 g_assert_cmpint (ret
, ==, -1);
1461 g_object_unref (task
);
1463 g_cancellable_reset (cancellable
);
1465 /* If return-on-cancel is TRUE, it does return early */
1466 thread_state
= THREAD_STARTING
;
1467 task
= g_task_new (NULL
, cancellable
, run_in_thread_sync_callback
, NULL
);
1468 g_task_set_return_on_cancel (task
, TRUE
);
1470 g_task_set_task_data (task
, (gpointer
)&thread_state
, NULL
);
1471 g_mutex_lock (&roc_init_mutex
);
1472 g_mutex_lock (&roc_finish_mutex
);
1473 runner_thread
= g_thread_new ("return-on-cancel-sync runner thread",
1474 cancel_sync_runner_thread
, task
);
1476 while (thread_state
== THREAD_STARTING
)
1477 g_cond_wait (&roc_init_cond
, &roc_init_mutex
);
1478 g_mutex_unlock (&roc_init_mutex
);
1480 g_assert (thread_state
== THREAD_RUNNING
);
1482 g_cancellable_cancel (cancellable
);
1483 g_thread_join (runner_thread
);
1484 g_assert (thread_state
== THREAD_RUNNING
);
1486 ret
= g_task_propagate_int (task
, &error
);
1487 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
1488 g_clear_error (&error
);
1489 g_assert_cmpint (ret
, ==, -1);
1491 g_object_unref (task
);
1493 while (thread_state
== THREAD_RUNNING
)
1494 g_cond_wait (&roc_finish_cond
, &roc_finish_mutex
);
1495 g_mutex_unlock (&roc_finish_mutex
);
1497 g_assert (thread_state
== THREAD_CANCELLED
);
1499 g_cancellable_reset (cancellable
);
1501 /* If the task is already cancelled before it starts, it returns
1502 * immediately, but the thread func still runs.
1504 thread_state
= THREAD_STARTING
;
1505 task
= g_task_new (NULL
, cancellable
, run_in_thread_sync_callback
, NULL
);
1506 g_task_set_return_on_cancel (task
, TRUE
);
1508 g_cancellable_cancel (cancellable
);
1510 g_task_set_task_data (task
, (gpointer
)&thread_state
, NULL
);
1511 g_mutex_lock (&roc_init_mutex
);
1512 g_mutex_lock (&roc_finish_mutex
);
1513 runner_thread
= g_thread_new ("return-on-cancel-sync runner thread",
1514 cancel_sync_runner_thread
, task
);
1516 g_thread_join (runner_thread
);
1517 g_assert (thread_state
== THREAD_STARTING
);
1519 ret
= g_task_propagate_int (task
, &error
);
1520 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
1521 g_clear_error (&error
);
1522 g_assert_cmpint (ret
, ==, -1);
1524 g_object_unref (task
);
1526 while (thread_state
== THREAD_STARTING
)
1527 g_cond_wait (&roc_init_cond
, &roc_init_mutex
);
1528 g_mutex_unlock (&roc_init_mutex
);
1530 g_assert (thread_state
== THREAD_RUNNING
);
1532 while (thread_state
== THREAD_RUNNING
)
1533 g_cond_wait (&roc_finish_cond
, &roc_finish_mutex
);
1534 g_mutex_unlock (&roc_finish_mutex
);
1536 g_assert (thread_state
== THREAD_CANCELLED
);
1538 g_object_unref (cancellable
);
1541 /* test_return_on_cancel_atomic: turning return-on-cancel on/off is
1545 GMutex roca_mutex_1
, roca_mutex_2
;
1546 GCond roca_cond_1
, roca_cond_2
;
1549 return_on_cancel_atomic_callback (GObject
*object
,
1550 GAsyncResult
*result
,
1553 gboolean
*callback_ran
= user_data
;
1554 GError
*error
= NULL
;
1557 g_assert (g_thread_self () == main_thread
);
1559 g_assert (object
== NULL
);
1560 g_assert (g_task_is_valid (result
, object
));
1561 g_assert (g_async_result_get_user_data (result
) == user_data
);
1562 g_assert (g_task_had_error (G_TASK (result
)));
1563 g_assert_false (g_task_get_completed (G_TASK (result
)));
1565 ret
= g_task_propagate_int (G_TASK (result
), &error
);
1566 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
1567 g_clear_error (&error
);
1568 g_assert_cmpint (ret
, ==, -1);
1570 g_assert (g_task_had_error (G_TASK (result
)));
1572 *callback_ran
= TRUE
;
1573 g_main_loop_quit (loop
);
1577 return_on_cancel_atomic_thread (GTask
*task
,
1578 gpointer source_object
,
1580 GCancellable
*cancellable
)
1582 gint
*state
= task_data
;
1584 g_assert (source_object
== g_task_get_source_object (task
));
1585 g_assert (task_data
== g_task_get_task_data (task
));
1586 g_assert (cancellable
== g_task_get_cancellable (task
));
1587 g_assert_false (g_task_get_completed (task
));
1589 g_assert (g_thread_self () != main_thread
);
1590 g_assert_cmpint (*state
, ==, 0);
1592 g_mutex_lock (&roca_mutex_1
);
1594 g_cond_signal (&roca_cond_1
);
1595 g_mutex_unlock (&roca_mutex_1
);
1597 g_mutex_lock (&roca_mutex_2
);
1598 if (g_task_set_return_on_cancel (task
, FALSE
))
1602 g_cond_signal (&roca_cond_2
);
1603 g_mutex_unlock (&roca_mutex_2
);
1605 g_mutex_lock (&roca_mutex_1
);
1606 if (g_task_set_return_on_cancel (task
, TRUE
))
1610 g_cond_signal (&roca_cond_1
);
1611 g_mutex_unlock (&roca_mutex_1
);
1613 g_mutex_lock (&roca_mutex_2
);
1614 if (g_task_set_return_on_cancel (task
, TRUE
))
1618 g_cond_signal (&roca_cond_2
);
1619 g_mutex_unlock (&roca_mutex_2
);
1621 g_task_return_int (task
, magic
);
1625 test_return_on_cancel_atomic (void)
1628 GCancellable
*cancellable
;
1629 volatile gint state
;
1630 gboolean notification_emitted
= FALSE
;
1631 gboolean callback_ran
;
1633 cancellable
= g_cancellable_new ();
1634 g_mutex_lock (&roca_mutex_1
);
1635 g_mutex_lock (&roca_mutex_2
);
1637 /* If we don't cancel it, each set_return_on_cancel() call will succeed */
1639 callback_ran
= FALSE
;
1640 task
= g_task_new (NULL
, cancellable
, return_on_cancel_atomic_callback
, &callback_ran
);
1641 g_task_set_return_on_cancel (task
, TRUE
);
1642 g_signal_connect (task
, "notify::completed",
1643 (GCallback
) completed_cb
, ¬ification_emitted
);
1645 g_task_set_task_data (task
, (gpointer
)&state
, NULL
);
1646 g_task_run_in_thread (task
, return_on_cancel_atomic_thread
);
1647 g_object_unref (task
);
1649 g_assert_cmpint (state
, ==, 0);
1652 g_cond_wait (&roca_cond_1
, &roca_mutex_1
);
1653 g_assert (state
== 1);
1656 g_cond_wait (&roca_cond_2
, &roca_mutex_2
);
1657 g_assert (state
== 2);
1660 g_cond_wait (&roca_cond_1
, &roca_mutex_1
);
1661 g_assert (state
== 4);
1664 g_cond_wait (&roca_cond_2
, &roca_mutex_2
);
1665 g_assert (state
== 6);
1667 /* callback assumes there'll be a cancelled error */
1668 g_cancellable_cancel (cancellable
);
1670 g_assert (callback_ran
== FALSE
);
1671 g_main_loop_run (loop
);
1672 g_assert (callback_ran
== TRUE
);
1673 g_assert_true (notification_emitted
);
1675 g_cancellable_reset (cancellable
);
1678 /* If we cancel while it's temporarily not return-on-cancel, the
1679 * task won't complete right away, and further
1680 * g_task_set_return_on_cancel() calls will return FALSE.
1683 callback_ran
= FALSE
;
1684 notification_emitted
= FALSE
;
1685 task
= g_task_new (NULL
, cancellable
, return_on_cancel_atomic_callback
, &callback_ran
);
1686 g_task_set_return_on_cancel (task
, TRUE
);
1687 g_signal_connect (task
, "notify::completed",
1688 (GCallback
) completed_cb
, ¬ification_emitted
);
1690 g_task_set_task_data (task
, (gpointer
)&state
, NULL
);
1691 g_task_run_in_thread (task
, return_on_cancel_atomic_thread
);
1692 g_object_unref (task
);
1694 g_assert_cmpint (state
, ==, 0);
1697 g_cond_wait (&roca_cond_1
, &roca_mutex_1
);
1698 g_assert (state
== 1);
1699 g_assert (g_task_get_return_on_cancel (task
));
1702 g_cond_wait (&roca_cond_2
, &roca_mutex_2
);
1703 g_assert (state
== 2);
1704 g_assert (!g_task_get_return_on_cancel (task
));
1706 g_cancellable_cancel (cancellable
);
1707 g_idle_add (idle_quit_loop
, NULL
);
1708 g_main_loop_run (loop
);
1709 g_assert (callback_ran
== FALSE
);
1712 g_cond_wait (&roca_cond_1
, &roca_mutex_1
);
1713 g_assert (state
== 5);
1714 g_assert (!g_task_get_return_on_cancel (task
));
1716 g_main_loop_run (loop
);
1717 g_assert (callback_ran
== TRUE
);
1718 g_assert_true (notification_emitted
);
1721 g_cond_wait (&roca_cond_2
, &roca_mutex_2
);
1722 g_assert (state
== 7);
1724 g_object_unref (cancellable
);
1725 g_mutex_unlock (&roca_mutex_1
);
1726 g_mutex_unlock (&roca_mutex_2
);
1729 /* test_return_pointer: memory management of pointer returns */
1732 test_return_pointer (void)
1734 GObject
*object
, *ret
;
1736 GCancellable
*cancellable
;
1737 GError
*error
= NULL
;
1739 /* If we don't read back the return value, the task will
1740 * run its destroy notify.
1742 object
= (GObject
*)g_dummy_object_new ();
1743 g_assert_cmpint (object
->ref_count
, ==, 1);
1744 g_object_add_weak_pointer (object
, (gpointer
*)&object
);
1746 task
= g_task_new (NULL
, NULL
, NULL
, NULL
);
1747 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
1748 g_task_return_pointer (task
, object
, g_object_unref
);
1749 g_assert_cmpint (object
->ref_count
, ==, 1);
1751 /* Task and object are reffed until the :completed notification in idle. */
1752 g_object_unref (task
);
1753 g_assert_nonnull (task
);
1754 g_assert_nonnull (object
);
1756 wait_for_completed_notification (task
);
1758 g_assert_null (task
);
1759 g_assert_null (object
);
1761 /* Likewise, if the return value is overwritten by an error */
1762 object
= (GObject
*)g_dummy_object_new ();
1763 g_assert_cmpint (object
->ref_count
, ==, 1);
1764 g_object_add_weak_pointer (object
, (gpointer
*)&object
);
1766 cancellable
= g_cancellable_new ();
1767 task
= g_task_new (NULL
, cancellable
, NULL
, NULL
);
1768 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
1769 g_task_return_pointer (task
, object
, g_object_unref
);
1770 g_assert_cmpint (object
->ref_count
, ==, 1);
1771 g_cancellable_cancel (cancellable
);
1772 g_assert_cmpint (object
->ref_count
, ==, 1);
1774 ret
= g_task_propagate_pointer (task
, &error
);
1775 g_assert (ret
== NULL
);
1776 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
1777 g_clear_error (&error
);
1778 g_assert_cmpint (object
->ref_count
, ==, 1);
1780 g_object_unref (task
);
1781 g_object_unref (cancellable
);
1782 g_assert_nonnull (task
);
1783 g_assert_nonnull (object
);
1785 wait_for_completed_notification (task
);
1787 g_assert_null (task
);
1788 g_assert_null (object
);
1790 /* If we read back the return value, we steal its ref */
1791 object
= (GObject
*)g_dummy_object_new ();
1792 g_assert_cmpint (object
->ref_count
, ==, 1);
1793 g_object_add_weak_pointer (object
, (gpointer
*)&object
);
1795 task
= g_task_new (NULL
, NULL
, NULL
, NULL
);
1796 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
1797 g_task_return_pointer (task
, object
, g_object_unref
);
1798 g_assert_cmpint (object
->ref_count
, ==, 1);
1800 ret
= g_task_propagate_pointer (task
, &error
);
1801 g_assert_no_error (error
);
1802 g_assert (ret
== object
);
1803 g_assert_cmpint (object
->ref_count
, ==, 1);
1805 g_object_unref (task
);
1806 g_assert_nonnull (task
);
1807 g_assert_cmpint (object
->ref_count
, ==, 1);
1808 g_object_unref (object
);
1809 g_assert (object
== NULL
);
1811 wait_for_completed_notification (task
);
1812 g_assert_null (task
);
1815 /* test_object_keepalive: GTask takes a ref on its source object */
1817 static GObject
*keepalive_object
;
1820 keepalive_callback (GObject
*object
,
1821 GAsyncResult
*result
,
1824 gssize
*result_out
= user_data
;
1825 GError
*error
= NULL
;
1827 g_assert (object
== keepalive_object
);
1828 g_assert (g_task_is_valid (result
, object
));
1829 g_assert (g_async_result_get_user_data (result
) == user_data
);
1830 g_assert (!g_task_had_error (G_TASK (result
)));
1831 g_assert_false (g_task_get_completed (G_TASK (result
)));
1833 *result_out
= g_task_propagate_int (G_TASK (result
), &error
);
1834 g_assert_no_error (error
);
1836 g_assert (!g_task_had_error (G_TASK (result
)));
1838 g_main_loop_quit (loop
);
1842 test_object_keepalive (void)
1848 gboolean notification_emitted
= FALSE
;
1850 keepalive_object
= object
= (GObject
*)g_dummy_object_new ();
1851 g_object_add_weak_pointer (object
, (gpointer
*)&object
);
1853 task
= g_task_new (object
, NULL
, keepalive_callback
, &result
);
1854 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
1855 g_signal_connect (task
, "notify::completed",
1856 (GCallback
) completed_cb
, ¬ification_emitted
);
1858 ref_count
= object
->ref_count
;
1859 g_assert_cmpint (ref_count
, >, 1);
1861 g_assert (g_task_get_source_object (task
) == object
);
1862 g_assert (g_async_result_get_source_object (G_ASYNC_RESULT (task
)) == object
);
1863 g_assert_cmpint (object
->ref_count
, ==, ref_count
+ 1);
1864 g_object_unref (object
);
1866 g_object_unref (object
);
1867 g_assert (object
!= NULL
);
1869 g_task_return_int (task
, magic
);
1870 g_main_loop_run (loop
);
1872 g_assert (object
!= NULL
);
1873 g_assert_cmpint (result
, ==, magic
);
1874 g_assert_true (notification_emitted
);
1876 g_object_unref (task
);
1877 g_assert (task
== NULL
);
1878 g_assert (object
== NULL
);
1881 /* test_legacy_error: legacy GSimpleAsyncResult handling */
1882 static void test_legacy_error (void);
1885 legacy_error_callback (GObject
*object
,
1886 GAsyncResult
*result
,
1889 gssize
*result_out
= user_data
;
1890 GError
*error
= NULL
;
1892 g_assert (object
== NULL
);
1893 g_assert (g_async_result_is_tagged (result
, test_legacy_error
));
1894 g_assert (g_async_result_get_user_data (result
) == user_data
);
1896 if (g_async_result_legacy_propagate_error (result
, &error
))
1898 g_assert (!g_task_is_valid (result
, object
));
1899 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
;
1900 g_assert (g_simple_async_result_is_valid (result
, object
, test_legacy_error
));
1901 G_GNUC_END_IGNORE_DEPRECATIONS
;
1903 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
);
1908 g_assert (g_task_is_valid (result
, object
));
1910 *result_out
= g_task_propagate_int (G_TASK (result
), NULL
);
1911 /* Might be error, might not */
1914 g_main_loop_quit (loop
);
1918 legacy_error_return (gpointer user_data
)
1920 if (G_IS_TASK (user_data
))
1922 GTask
*task
= user_data
;
1924 g_task_return_int (task
, magic
);
1925 g_object_unref (task
);
1929 GSimpleAsyncResult
*simple
= G_SIMPLE_ASYNC_RESULT (user_data
);
1931 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
;
1932 g_simple_async_result_set_error (simple
,
1936 g_simple_async_result_complete (simple
);
1937 G_GNUC_END_IGNORE_DEPRECATIONS
;
1938 g_object_unref (simple
);
1945 test_legacy_error (void)
1948 GSimpleAsyncResult
*simple
;
1952 task
= g_task_new (NULL
, NULL
, legacy_error_callback
, &result
);
1953 g_task_set_source_tag (task
, test_legacy_error
);
1954 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
1956 g_idle_add (legacy_error_return
, task
);
1957 g_main_loop_run (loop
);
1959 g_assert_cmpint (result
, ==, magic
);
1960 g_assert (task
== NULL
);
1963 task
= g_task_new (NULL
, NULL
, legacy_error_callback
, &result
);
1964 g_task_set_source_tag (task
, test_legacy_error
);
1965 g_object_add_weak_pointer (G_OBJECT (task
), (gpointer
*)&task
);
1967 g_task_return_new_error (task
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
1969 g_object_unref (task
);
1970 g_main_loop_run (loop
);
1972 g_assert_cmpint (result
, ==, -1);
1973 g_assert (task
== NULL
);
1975 /* GSimpleAsyncResult error */
1976 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
;
1977 simple
= g_simple_async_result_new (NULL
, legacy_error_callback
, &result
,
1979 G_GNUC_END_IGNORE_DEPRECATIONS
;
1980 g_object_add_weak_pointer (G_OBJECT (simple
), (gpointer
*)&simple
);
1982 g_idle_add (legacy_error_return
, simple
);
1983 g_main_loop_run (loop
);
1985 g_assert_cmpint (result
, ==, -2);
1986 g_assert (simple
== NULL
);
1991 main (int argc
, char **argv
)
1995 g_test_init (&argc
, &argv
, NULL
);
1997 loop
= g_main_loop_new (NULL
, FALSE
);
1998 main_thread
= g_thread_self ();
1999 magic
= g_get_monotonic_time ();
2001 g_test_add_func ("/gtask/basic", test_basic
);
2002 g_test_add_func ("/gtask/error", test_error
);
2003 g_test_add_func ("/gtask/return-from-same-iteration", test_return_from_same_iteration
);
2004 g_test_add_func ("/gtask/return-from-toplevel", test_return_from_toplevel
);
2005 g_test_add_func ("/gtask/return-from-anon-thread", test_return_from_anon_thread
);
2006 g_test_add_func ("/gtask/return-from-wrong-thread", test_return_from_wrong_thread
);
2007 g_test_add_func ("/gtask/no-callback", test_no_callback
);
2008 g_test_add_func ("/gtask/report-error", test_report_error
);
2009 g_test_add_func ("/gtask/priority", test_priority
);
2010 g_test_add_func ("/gtask/check-cancellable", test_check_cancellable
);
2011 g_test_add_func ("/gtask/return-if-cancelled", test_return_if_cancelled
);
2012 g_test_add_func ("/gtask/run-in-thread", test_run_in_thread
);
2013 g_test_add_func ("/gtask/run-in-thread-sync", test_run_in_thread_sync
);
2014 g_test_add_func ("/gtask/run-in-thread-priority", test_run_in_thread_priority
);
2015 g_test_add_func ("/gtask/run-in-thread-nested", test_run_in_thread_nested
);
2016 g_test_add_func ("/gtask/run-in-thread-overflow", test_run_in_thread_overflow
);
2017 g_test_add_func ("/gtask/return-on-cancel", test_return_on_cancel
);
2018 g_test_add_func ("/gtask/return-on-cancel-sync", test_return_on_cancel_sync
);
2019 g_test_add_func ("/gtask/return-on-cancel-atomic", test_return_on_cancel_atomic
);
2020 g_test_add_func ("/gtask/return-pointer", test_return_pointer
);
2021 g_test_add_func ("/gtask/object-keepalive", test_object_keepalive
);
2022 g_test_add_func ("/gtask/legacy-error", test_legacy_error
);
2026 g_main_loop_unref (loop
);