[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / gio / gtask.c
index 62a4440..51259bd 100644 (file)
@@ -82,7 +82,7 @@
  *       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);
@@ -541,7 +540,7 @@ struct _GTask {
   GDestroyNotify task_data_destroy;
 
   GMainContext *context;
-  guint64 creation_time;
+  gint64 creation_time;
   gint priority;
   GCancellable *cancellable;
   gboolean check_cancellable;
@@ -1060,7 +1059,7 @@ g_task_get_return_on_cancel (GTask *task)
  *
  * 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
  */
@@ -1137,6 +1136,7 @@ g_task_return (GTask           *task,
   /* 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);
 }
 
@@ -1274,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.
@@ -1664,7 +1670,7 @@ g_task_return_new_error (GTask           *task,
  * 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
  */
@@ -1722,7 +1728,7 @@ g_task_had_error (GTask *task)
  * 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