From 6f3d57d2ee271017f37ebdceb1e15efa7ce0ac49 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Mon, 3 Dec 2018 20:10:41 +0100 Subject: [PATCH] gtask: Return cancelled tasks asynchronously Once cancelled, a GTask's callback should not only be invoked asynchronously with respect to the creation of the task, but also with respect to the GCancellable::cancelled handler. This is particularly relevant in cases where the cancellation happened in the same thread where the task is running. Spotted by Dan Winship and Michael Catanzaro. Closes https://gitlab.gnome.org/GNOME/glib/issues/1608 --- gio/gtask.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/gio/gtask.c b/gio/gtask.c index aa98f752c..346d2ec5b 100644 --- a/gio/gtask.c +++ b/gio/gtask.c @@ -1,6 +1,6 @@ /* GIO - GLib Input, Output and Streaming Library * - * Copyright 2011 Red Hat, Inc. + * Copyright 2011-2018 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1260,9 +1260,18 @@ g_task_return (GTask *task, */ if (g_source_get_time (source) > task->creation_time) { - g_task_return_now (task); - g_object_unref (task); - return; + /* Finally, if the task has been cancelled, we shouldn't + * return synchronously from inside the + * GCancellable::cancelled handler. It's easier to run + * another iteration of the main loop than tracking how the + * cancellation was handled. + */ + if (!g_cancellable_is_cancelled (task->cancellable)) + { + g_task_return_now (task); + g_object_unref (task); + return; + } } }