mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-02 15:33:39 +02:00
gio/cancellable: Always add reference while emitting cancelled signal
When a non-cancelled cancellable ::cancelled signal callback is called the cancellable has enough references so that it can be unreferenced on the callback itself. However this doesn't happen if the cancellable has been already cancelled at the moment we connect to it. To prevent this, add a temporary reference before calling the signal callback. Note that we do this also if the callback has not been already cancelled to prevent that we may end up calling a toggle-notify callback while we are locked. Add tests Closes: #3643
This commit is contained in:
@@ -909,6 +909,25 @@ test_connect_to_disposing_callback (void)
|
||||
g_assert_null (cancellable);
|
||||
}
|
||||
|
||||
static void
|
||||
test_connect_cancelled_to_disposing_callback (void)
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
gulong id;
|
||||
|
||||
g_test_summary ("A cancellable signal callback can unref the cancellable");
|
||||
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3643");
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
g_object_add_weak_pointer (G_OBJECT (cancellable), (gpointer *) &cancellable);
|
||||
|
||||
g_cancellable_cancel (cancellable);
|
||||
id = g_cancellable_connect (cancellable, G_CALLBACK (assert_references_and_unref),
|
||||
GINT_TO_POINTER (2), NULL);
|
||||
g_assert_cmpuint (id, ==, 0);
|
||||
g_assert_null (cancellable);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -917,6 +936,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/cancellable/multiple-concurrent", test_cancel_multiple_concurrent);
|
||||
g_test_add_func ("/cancellable/null", test_cancel_null);
|
||||
g_test_add_func ("/cancellable/connect-to-disposing-callback", test_connect_to_disposing_callback);
|
||||
g_test_add_func ("/cancellable/connect-cancelled-to-disposing-callback", test_connect_cancelled_to_disposing_callback);
|
||||
g_test_add_func ("/cancellable/disconnect-on-cancelled-callback-hangs", test_cancellable_disconnect_on_cancelled_callback_hangs);
|
||||
g_test_add_func ("/cancellable/resets-on-cancel-callback-hangs", test_cancellable_reset_on_cancelled_callback_hangs);
|
||||
g_test_add_func ("/cancellable/poll-fd", test_cancellable_poll_fd);
|
||||
|
Reference in New Issue
Block a user