GTask: convert long desc to markdown

Use markdown sections and lists here.
This commit is contained in:
Matthias Clasen 2014-01-31 22:29:13 -05:00
parent ed2bb95330
commit ba307a0c52

View File

@ -30,29 +30,27 @@
* @include: gio/gio.h * @include: gio/gio.h
* @see_also: #GAsyncResult * @see_also: #GAsyncResult
* *
* <para> * A #GTask represents and manages a cancellable "task".
* A #GTask represents and manages a cancellable "task". *
* </para> * ## Asynchronous operations
* <refsect2> *
* <title>Asynchronous operations</title> * The most common usage of #GTask is as a #GAsyncResult, to
* <para> * manage data during an asynchronous operation. You call
* The most common usage of #GTask is as a #GAsyncResult, to * g_task_new() in the "start" method, followed by
* manage data during an asynchronous operation. You call * g_task_set_task_data() and the like if you need to keep some
* g_task_new() in the "start" method, followed by * additional data associated with the task, and then pass the
* g_task_set_task_data() and the like if you need to keep some * task object around through your asynchronous operation.
* additional data associated with the task, and then pass the * Eventually, you will call a method such as
* task object around through your asynchronous operation. * g_task_return_pointer() or g_task_return_error(), which will
* Eventually, you will call a method such as * save the value you give it and then invoke the task's callback
* g_task_return_pointer() or g_task_return_error(), which will * function (waiting until the next iteration of the main
* save the value you give it and then invoke the task's callback * loop first, if necessary). The caller will pass the #GTask back
* function (waiting until the next iteration of the main * to the operation's finish function (as a #GAsyncResult), and
* loop first, if necessary). The caller will pass the #GTask back * you can use g_task_propagate_pointer() or the like to extract
* to the operation's finish function (as a #GAsyncResult), and * the return value.
* you can use g_task_propagate_pointer() or the like to extract *
* the return value. * Here is an example for using GTask as a GAsyncResult:
* </para> * |[
* Here is an example for using GTask as a GAsyncResult:
* |[
* typedef struct { * typedef struct {
* CakeFrostingType frosting; * CakeFrostingType frosting;
* char *message; * char *message;
@ -145,23 +143,21 @@
* return g_task_propagate_pointer (G_TASK (result), error); * return g_task_propagate_pointer (G_TASK (result), error);
* } * }
* ]| * ]|
* </refsect2> *
* <refsect2> * ## Chained asynchronous operations
* <title>Chained asynchronous operations</title> *
* <para> * #GTask also tries to simplify asynchronous operations that
* #GTask also tries to simplify asynchronous operations that * internally chain together several smaller asynchronous
* internally chain together several smaller asynchronous * operations. g_task_get_cancellable(), g_task_get_context(), and
* operations. g_task_get_cancellable(), g_task_get_context(), and * g_task_get_priority() allow you to get back the task's
* g_task_get_priority() allow you to get back the task's * #GCancellable, #GMainContext, and <link
* #GCancellable, #GMainContext, and <link * linkend="io-priority">I/O priority</link> when starting a new
* linkend="io-priority">I/O priority</link> when starting a new * subtask, so you don't have to keep track of them yourself.
* subtask, so you don't have to keep track of them yourself. * g_task_attach_source() simplifies the case of waiting for a
* g_task_attach_source() simplifies the case of waiting for a * source to fire (automatically using the correct #GMainContext
* source to fire (automatically using the correct #GMainContext * and priority).
* and priority). *
* </para> * Here is an example for chained asynchronous operations:
* <para>
* Here is an example for chained asynchronous operations:
* |[ * |[
* typedef struct { * typedef struct {
* Cake *cake; * Cake *cake;
@ -288,18 +284,15 @@
* return g_task_propagate_pointer (G_TASK (result), error); * return g_task_propagate_pointer (G_TASK (result), error);
* } * }
* ]| * ]|
* </para> *
* </refsect2> * ## Asynchronous operations from synchronous ones
* <refsect2> *
* <title>Asynchronous operations from synchronous ones</title> * You can use g_task_run_in_thread() to turn a synchronous
* <para> * operation into an asynchronous one, by running it in a thread
* You can use g_task_run_in_thread() to turn a synchronous * which will then dispatch the result back to the caller's
* operation into an asynchronous one, by running it in a thread * #GMainContext when it completes.
* which will then dispatch the result back to the caller's *
* #GMainContext when it completes. * Running a task in a thread:
* </para>
* <para>
* Running a task in a thread:
* |[ * |[
* typedef struct { * typedef struct {
* guint radius; * guint radius;
@ -368,25 +361,22 @@
* return g_task_propagate_pointer (G_TASK (result), error); * return g_task_propagate_pointer (G_TASK (result), error);
* } * }
* ]| * ]|
* </para> *
* </refsect2> * ## Adding cancellability to uncancellable tasks
* <refsect2> *
* <title>Adding cancellability to uncancellable tasks</title> * Finally, g_task_run_in_thread() and g_task_run_in_thread_sync()
* <para> * can be used to turn an uncancellable operation into a
* Finally, g_task_run_in_thread() and g_task_run_in_thread_sync() * cancellable one. If you call g_task_set_return_on_cancel(),
* can be used to turn an uncancellable operation into a * passing %TRUE, then if the task's #GCancellable is cancelled,
* cancellable one. If you call g_task_set_return_on_cancel(), * it will return control back to the caller immediately, while
* passing %TRUE, then if the task's #GCancellable is cancelled, * allowing the task thread to continue running in the background
* it will return control back to the caller immediately, while * (and simply discarding its result when it finally does finish).
* allowing the task thread to continue running in the background * Provided that the task thread is careful about how it uses
* (and simply discarding its result when it finally does finish). * locks and other externally-visible resources, this allows you
* Provided that the task thread is careful about how it uses * to make "GLib-friendly" asynchronous and cancellable
* locks and other externally-visible resources, this allows you * synchronous variants of blocking APIs.
* to make "GLib-friendly" asynchronous and cancellable *
* synchronous variants of blocking APIs. * Cancelling a task:
* </para>
* <para>
* Cancelling a task:
* |[ * |[
* static void * static void
* bake_cake_thread (GTask *task, * bake_cake_thread (GTask *task,
@ -439,7 +429,7 @@
* GAsyncReadyCallback callback, * GAsyncReadyCallback callback,
* gpointer user_data) * gpointer user_data)
* { * {
* CakeData *cake_data; J* CakeData *cake_data;
* GTask *task; * GTask *task;
* *
* cake_data = g_slice_new (CakeData); * cake_data = g_slice_new (CakeData);
@ -477,80 +467,62 @@
* return cake; * return cake;
* } * }
* ]| * ]|
* </para> *
* </refsect2> * ## Porting from GSimpleAsyncResult
* <refsect2> *
* <title>Porting from <literal>GSimpleAsyncResult</literal></title> * #GTask's API attempts to be simpler than #GSimpleAsyncResult's
* <para> * in several ways:
* #GTask's API attempts to be simpler than #GSimpleAsyncResult's * - You can save task-specific data with g_task_set_task_data(), and
* in several ways: * retrieve it later with g_task_get_task_data(). This replaces the
* </para> * abuse of g_simple_async_result_set_op_res_gpointer() for the same
* <itemizedlist> * purpose with #GSimpleAsyncResult.
* <listitem><para> * - In addition to the task data, #GTask also keeps track of the
* You can save task-specific data with g_task_set_task_data(), and * <link linkend="io-priority">priority</link>, #GCancellable, and
* retrieve it later with g_task_get_task_data(). This replaces the * #GMainContext associated with the task, so tasks that consist of
* abuse of g_simple_async_result_set_op_res_gpointer() for the same * a chain of simpler asynchronous operations will have easy access
* purpose with #GSimpleAsyncResult. * to those values when starting each sub-task.
* </para></listitem> * - g_task_return_error_if_cancelled() provides simplified
* <listitem><para> * handling for cancellation. In addition, cancellation
* In addition to the task data, #GTask also keeps track of the * overrides any other #GTask return value by default, like
* <link linkend="io-priority">priority</link>, #GCancellable, and * #GSimpleAsyncResult does when
* #GMainContext associated with the task, so tasks that consist of * g_simple_async_result_set_check_cancellable() is called.
* a chain of simpler asynchronous operations will have easy access * (You can use g_task_set_check_cancellable() to turn off that
* to those values when starting each sub-task. * behavior.) On the other hand, g_task_run_in_thread()
* </para></listitem> * guarantees that it will always run your
* <listitem><para> * <literal>task_func</literal>, even if the task's #GCancellable
* g_task_return_error_if_cancelled() provides simplified * is already cancelled before the task gets a chance to run;
* handling for cancellation. In addition, cancellation * you can start your <literal>task_func</literal> with a
* overrides any other #GTask return value by default, like * g_task_return_error_if_cancelled() check if you need the
* #GSimpleAsyncResult does when * old behavior.
* g_simple_async_result_set_check_cancellable() is called. * - The "return" methods (eg, g_task_return_pointer())
* (You can use g_task_set_check_cancellable() to turn off that * automatically cause the task to be "completed" as well, and
* behavior.) On the other hand, g_task_run_in_thread() * there is no need to worry about the "complete" vs "complete
* guarantees that it will always run your * in idle" distinction. (#GTask automatically figures out
* <literal>task_func</literal>, even if the task's #GCancellable * whether the task's callback can be invoked directly, or
* is already cancelled before the task gets a chance to run; * if it needs to be sent to another #GMainContext, or delayed
* you can start your <literal>task_func</literal> with a * until the next iteration of the current #GMainContext.)
* g_task_return_error_if_cancelled() check if you need the * - The "finish" functions for #GTask-based operations are generally
* old behavior. * much simpler than #GSimpleAsyncResult ones, normally consisting
* </para></listitem> * of only a single call to g_task_propagate_pointer() or the like.
* <listitem><para> * Since g_task_propagate_pointer() "steals" the return value from
* The "return" methods (eg, g_task_return_pointer()) * the #GTask, it is not necessary to juggle pointers around to
* automatically cause the task to be "completed" as well, and * prevent it from being freed twice.
* there is no need to worry about the "complete" vs "complete * - With #GSimpleAsyncResult, it was common to call
* in idle" distinction. (#GTask automatically figures out * g_simple_async_result_propagate_error() from the
* whether the task's callback can be invoked directly, or * <literal>_finish()</literal> wrapper function, and have
* if it needs to be sent to another #GMainContext, or delayed * virtual method implementations only deal with successful
* until the next iteration of the current #GMainContext.) * returns. This behavior is deprecated, because it makes it
* </para></listitem> * difficult for a subclass to chain to a parent class's async
* <listitem><para> * methods. Instead, the wrapper function should just be a
* The "finish" functions for #GTask-based operations are generally * simple wrapper, and the virtual method should call an
* much simpler than #GSimpleAsyncResult ones, normally consisting * appropriate <literal>g_task_propagate_</literal> function.
* of only a single call to g_task_propagate_pointer() or the like. * Note that wrapper methods can now use
* Since g_task_propagate_pointer() "steals" the return value from * g_async_result_legacy_propagate_error() to do old-style
* the #GTask, it is not necessary to juggle pointers around to * #GSimpleAsyncResult error-returning behavior, and
* prevent it from being freed twice. * g_async_result_is_tagged() to check if a result is tagged as
* </para></listitem> * having come from the <literal>_async()</literal> wrapper
* <listitem><para> * function (for "short-circuit" results, such as when passing
* With #GSimpleAsyncResult, it was common to call * 0 to g_input_stream_read_async()).
* g_simple_async_result_propagate_error() from the
* <literal>_finish()</literal> wrapper function, and have
* virtual method implementations only deal with successful
* returns. This behavior is deprecated, because it makes it
* difficult for a subclass to chain to a parent class's async
* methods. Instead, the wrapper function should just be a
* simple wrapper, and the virtual method should call an
* appropriate <literal>g_task_propagate_</literal> function.
* Note that wrapper methods can now use
* g_async_result_legacy_propagate_error() to do old-style
* #GSimpleAsyncResult error-returning behavior, and
* g_async_result_is_tagged() to check if a result is tagged as
* having come from the <literal>_async()</literal> wrapper
* function (for "short-circuit" results, such as when passing
* 0 to g_input_stream_read_async()).
* </para></listitem>
* </itemizedlist>
* </refsect2>
*/ */
/** /**