* if (!cake_decorate (cake, decoration->frosting, decoration->message, &error))
* {
* g_object_unref (cake);
- * /* g_task_return_error() takes ownership of error */
+ * // g_task_return_error() takes ownership of error
* g_task_return_error (task, error);
* g_object_unref (task);
* return;
* cake = _baker_get_cached_cake (self, radius, flavor, frosting, message);
* if (cake != NULL)
* {
- * /* _baker_get_cached_cake() returns a reffed cake */
+ * // _baker_get_cached_cake() returns a reffed cake
* g_task_return_pointer (task, cake, g_object_unref);
* g_object_unref (task);
* return;
* return;
* }
*
- * /* baking_data_free() will drop its ref on the cake, so
- * * we have to take another here to give to the caller.
- * */
+ * // baking_data_free() will drop its ref on the cake, so we have to
+ * // take another here to give to the caller.
* g_task_return_pointer (result, g_object_ref (cake), g_object_unref);
* g_object_unref (task);
* }
*
* bd->cake = cake;
*
- * /* Bail out now if the user has already cancelled */
+ * // Bail out now if the user has already cancelled
* if (g_task_return_error_if_cancelled (task))
* {
* g_object_unref (task);
* GSource *source;
*
* source = cake_decorator_wait_source_new (cake);
- * /* Attach @source to @task's GMainContext and have it call
- * * decorator_ready() when it is ready.
- * */
+ * // Attach @source to @task's GMainContext and have it call
+ * // decorator_ready() when it is ready.
* g_task_attach_source (task, source,
* G_CALLBACK (decorator_ready));
* g_source_unref (source);
* 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 *
* return;
* }
*
- * /* If the task has already been cancelled, then we don't
- * * want to add the cake to the cake cache. Likewise, we don't
- * * want to have the task get cancelled in the middle of
- * * updating the cache. g_task_set_return_on_cancel() will
- * * return %TRUE here if it managed to disable return-on-cancel,
- * * or %FALSE if the task was cancelled before it could.
- * */
+ * // If the task has already been cancelled, then we don't want to add
+ * // the cake to the cake cache. Likewise, we don't want to have the
+ * // task get cancelled in the middle of updating the cache.
+ * // g_task_set_return_on_cancel() will return %TRUE here if it managed
+ * // to disable return-on-cancel, or %FALSE if the task was cancelled
+ * // before it could.
* if (g_task_set_return_on_cancel (task, FALSE))
* {
- * /* If the caller cancels at this point, their
- * * GAsyncReadyCallback won't be invoked until we return,
- * * so we don't have to worry that this code will run at
- * * the same time as that code does. But if there were
- * * other functions that might look at the cake cache,
- * * then we'd probably need a GMutex here as well.
- * */
+ * // If the caller cancels at this point, their
+ * // GAsyncReadyCallback won't be invoked until we return,
+ * // so we don't have to worry that this code will run at
+ * // the same time as that code does. But if there were
+ * // other functions that might look at the cake cache,
+ * // then we'd probably need a GMutex here as well.
* baker_add_cake_to_cache (baker, cake);
* g_task_return_pointer (task, cake, g_object_unref);
* }
* GAsyncReadyCallback callback,
* gpointer user_data)
* {
- J* CakeData *cake_data;
+ * CakeData *cake_data;
* GTask *task;
*
* cake_data = g_slice_new (CakeData);
- * /* ... */
+ *
+ * ...
*
* task = g_task_new (self, cancellable, callback, user_data);
* g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free);
* Cake *cake;
*
* cake_data = g_slice_new (CakeData);
- * /* ... */
+ *
+ * ...
*
* task = g_task_new (self, cancellable, NULL, NULL);
* g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free);
GDestroyNotify task_data_destroy;
GMainContext *context;
- guint64 creation_time;
+ gint64 creation_time;
gint priority;
GCancellable *cancellable;
gboolean check_cancellable;
*
* Gets @task's source tag. See g_task_set_source_tag().
*
- * Return value: (transfer none): @task's source tag
+ * Returns: (transfer none): @task's source tag
*
* Since: 2.36
*/
/* Otherwise, complete in the next iteration */
source = g_idle_source_new ();
g_task_attach_source (task, source, complete_in_idle_cb);
+ g_source_set_name (source, "[gio] complete_in_idle_cb");
g_source_unref (source);
}
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.
* g_task_return_pointer() for more discussion of exactly what this
* means).
*
- * Return value: %TRUE if @task has been cancelled, %FALSE if not
+ * Returns: %TRUE if @task has been cancelled, %FALSE if not
*
* Since: 2.36
*/
* source object (or that @source_object is %NULL and @result has no
* source object). This can be used in g_return_if_fail() checks.
*
- * Return value: %TRUE if @result and @source_object are valid, %FALSE
+ * Returns: %TRUE if @result and @source_object are valid, %FALSE
* if not
*
* Since: 2.36