X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgtask.c;h=51259bd54244c75c0878011ec59096c438447fbb;hb=7a1aaaa1fa02679ecf335a19fffe3f55505921b5;hp=30d36aeb685988ad82d4865a6f007d3886975038;hpb=8792609e15394967cab526838b83f90acb401663;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gtask.c b/gio/gtask.c index 30d36ae..51259bd 100644 --- a/gio/gtask.c +++ b/gio/gtask.c @@ -346,6 +346,7 @@ * task = g_task_new (self, cancellable, callback, user_data); * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); * g_task_run_in_thread (task, bake_cake_thread); + * g_object_unref (task); * } * * Cake * @@ -539,7 +540,7 @@ struct _GTask { GDestroyNotify task_data_destroy; GMainContext *context; - guint64 creation_time; + gint64 creation_time; gint priority; GCancellable *cancellable; gboolean check_cancellable; @@ -1273,16 +1274,22 @@ g_task_start_task_thread (GTask *task, return; } + /* This introduces a reference count loop between the GTask and + * GCancellable, but is necessary to avoid a race on finalising the GTask + * between task_thread_cancelled() (in one thread) and + * g_task_thread_complete() (in another). + * + * Accordingly, the signal handler *must* be removed once the task has + * completed. + */ g_signal_connect_data (task->cancellable, "cancelled", G_CALLBACK (task_thread_cancelled), g_object_ref (task), task_thread_cancelled_disconnect_notify, 0); } - g_thread_pool_push (task_pool, g_object_ref (task), &task->error); - if (task->error) - task->thread_complete = TRUE; - else if (g_private_get (&task_private)) + g_thread_pool_push (task_pool, g_object_ref (task), NULL); + if (g_private_get (&task_private)) { /* This thread is being spawned from another GTask thread, so * bump up max-threads so we don't starve.