Copyright | Will Thompson Iñaki García Etxebarria and Jonas Platte |
---|---|
License | LGPL-2.1 |
Maintainer | Iñaki García Etxebarria (garetxe@gmail.com) |
Safe Haskell | None |
Language | Haskell2010 |
- Exported types
- Methods
- getCancellable
- getCheckCancellable
- getCompleted
- getContext
- getPriority
- getReturnOnCancel
- getSourceObject
- getSourceTag
- getTaskData
- hadError
- isValid
- new
- propagateBoolean
- propagateInt
- propagatePointer
- reportError
- returnBoolean
- returnError
- returnErrorIfCancelled
- returnInt
- returnPointer
- setCheckCancellable
- setPriority
- setReturnOnCancel
- setSourceTag
- setTaskData
- Properties
A Task
represents and manages a cancellable "task".
Asynchronous operations
The most common usage of Task
is as a AsyncResult
, to
manage data during an asynchronous operation. You call
taskNew
in the "start" method, followed by
taskSetTaskData
and the like if you need to keep some
additional data associated with the task, and then pass the
task object around through your asynchronous operation.
Eventually, you will call a method such as
taskReturnPointer
or taskReturnError
, which will
save the value you give it and then invoke the task's callback
function in the
[thread-default main context][g-main-context-push-thread-default]
where it was created (waiting until the next iteration of the main
loop first, if necessary). The caller will pass the Task
back to
the operation's finish function (as a AsyncResult
), and you can
can use taskPropagatePointer
or the like to extract the
return value.
Here is an example for using GTask as a GAsyncResult:
C code
typedef struct { CakeFrostingType frosting; char *message; } DecorationData; static void decoration_data_free (DecorationData *decoration) { g_free (decoration->message); g_slice_free (DecorationData, decoration); } static void baked_cb (Cake *cake, gpointer user_data) { GTask *task = user_data; DecorationData *decoration = g_task_get_task_data (task); GError *error = NULL; if (cake == NULL) { g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR, "Go to the supermarket"); g_object_unref (task); return; } 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 (task, error); g_object_unref (task); return; } g_task_return_pointer (task, cake, g_object_unref); g_object_unref (task); } void baker_bake_cake_async (Baker *self, guint radius, CakeFlavor flavor, CakeFrostingType frosting, const char *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GTask *task; DecorationData *decoration; Cake *cake; task = g_task_new (self, cancellable, callback, user_data); if (radius < 3) { g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_TOO_SMALL, "%ucm radius cakes are silly", radius); 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 g_task_return_pointer (task, cake, g_object_unref); g_object_unref (task); return; } decoration = g_slice_new (DecorationData); decoration->frosting = frosting; decoration->message = g_strdup (message); g_task_set_task_data (task, decoration, (GDestroyNotify) decoration_data_free); _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task); } Cake * baker_bake_cake_finish (Baker *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), NULL); return g_task_propagate_pointer (G_TASK (result), error); }
Chained asynchronous operations
Task
also tries to simplify asynchronous operations that
internally chain together several smaller asynchronous
operations. taskGetCancellable
, taskGetContext
,
and taskGetPriority
allow you to get back the task's
Cancellable
, MainContext
, and [I/O priority][io-priority]
when starting a new subtask, so you don't have to keep track
of them yourself. g_task_attach_source()
simplifies the case
of waiting for a source to fire (automatically using the correct
MainContext
and priority).
Here is an example for chained asynchronous operations:
C code
typedef struct { Cake *cake; CakeFrostingType frosting; char *message; } BakingData; static void decoration_data_free (BakingData *bd) { if (bd->cake) g_object_unref (bd->cake); g_free (bd->message); g_slice_free (BakingData, bd); } static void decorated_cb (Cake *cake, GAsyncResult *result, gpointer user_data) { GTask *task = user_data; GError *error = NULL; if (!cake_decorate_finish (cake, result, &error)) { g_object_unref (cake); g_task_return_error (task, error); g_object_unref (task); return; } // 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 (task, g_object_ref (cake), g_object_unref); g_object_unref (task); } static gboolean decorator_ready (gpointer user_data) { GTask *task = user_data; BakingData *bd = g_task_get_task_data (task); cake_decorate_async (bd->cake, bd->frosting, bd->message, g_task_get_cancellable (task), decorated_cb, task); return G_SOURCE_REMOVE; } static void baked_cb (Cake *cake, gpointer user_data) { GTask *task = user_data; BakingData *bd = g_task_get_task_data (task); GError *error = NULL; if (cake == NULL) { g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR, "Go to the supermarket"); g_object_unref (task); return; } bd->cake = cake; // Bail out now if the user has already cancelled if (g_task_return_error_if_cancelled (task)) { g_object_unref (task); return; } if (cake_decorator_available (cake)) decorator_ready (task); else { 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. g_task_attach_source (task, source, decorator_ready); g_source_unref (source); } } void baker_bake_cake_async (Baker *self, guint radius, CakeFlavor flavor, CakeFrostingType frosting, const char *message, gint priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GTask *task; BakingData *bd; task = g_task_new (self, cancellable, callback, user_data); g_task_set_priority (task, priority); bd = g_slice_new0 (BakingData); bd->frosting = frosting; bd->message = g_strdup (message); g_task_set_task_data (task, bd, (GDestroyNotify) baking_data_free); _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task); } Cake * baker_bake_cake_finish (Baker *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), NULL); return g_task_propagate_pointer (G_TASK (result), error); }
Asynchronous operations from synchronous ones
You can use g_task_run_in_thread()
to turn a synchronous
operation into an asynchronous one, by running it in a thread.
When it completes, the result will be dispatched to the
[thread-default main context][g-main-context-push-thread-default]
where the Task
was created.
Running a task in a thread:
C code
typedef struct { guint radius; CakeFlavor flavor; CakeFrostingType frosting; char *message; } CakeData; static void cake_data_free (CakeData *cake_data) { g_free (cake_data->message); g_slice_free (CakeData, cake_data); } static void bake_cake_thread (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { Baker *self = source_object; CakeData *cake_data = task_data; Cake *cake; GError *error = NULL; cake = bake_cake (baker, cake_data->radius, cake_data->flavor, cake_data->frosting, cake_data->message, cancellable, &error); if (cake) g_task_return_pointer (task, cake, g_object_unref); else g_task_return_error (task, error); } void baker_bake_cake_async (Baker *self, guint radius, CakeFlavor flavor, CakeFrostingType frosting, const char *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CakeData *cake_data; GTask *task; cake_data = g_slice_new (CakeData); cake_data->radius = radius; cake_data->flavor = flavor; cake_data->frosting = frosting; cake_data->message = g_strdup (message); 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 * baker_bake_cake_finish (Baker *self, GAsyncResult *result, GError **error) { g_return_val_if_fail (g_task_is_valid (result, self), NULL); return g_task_propagate_pointer (G_TASK (result), error); }
Adding cancellability to uncancellable tasks
Finally, g_task_run_in_thread()
and g_task_run_in_thread_sync()
can be used to turn an uncancellable operation into a
cancellable one. If you call taskSetReturnOnCancel
,
passing True
, then if the task's Cancellable
is cancelled,
it will return control back to the caller immediately, while
allowing the task thread to continue running in the background
(and simply discarding its result when it finally does finish).
Provided that the task thread is careful about how it uses
locks and other externally-visible resources, this allows you
to make "GLib-friendly" asynchronous and cancellable
synchronous variants of blocking APIs.
Cancelling a task:
C code
static void bake_cake_thread (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { Baker *self = source_object; CakeData *cake_data = task_data; Cake *cake; GError *error = NULL; cake = bake_cake (baker, cake_data->radius, cake_data->flavor, cake_data->frosting, cake_data->message, &error); if (error) { g_task_return_error (task, error); 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 (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. baker_add_cake_to_cache (baker, cake); g_task_return_pointer (task, cake, g_object_unref); } } void baker_bake_cake_async (Baker *self, guint radius, CakeFlavor flavor, CakeFrostingType frosting, const char *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_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); g_task_set_return_on_cancel (task, TRUE); g_task_run_in_thread (task, bake_cake_thread); } Cake * baker_bake_cake_sync (Baker *self, guint radius, CakeFlavor flavor, CakeFrostingType frosting, const char *message, GCancellable *cancellable, GError **error) { CakeData *cake_data; GTask *task; 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); g_task_set_return_on_cancel (task, TRUE); g_task_run_in_thread_sync (task, bake_cake_thread); cake = g_task_propagate_pointer (task, error); g_object_unref (task); return cake; }
Porting from GSimpleAsyncResult
'GI.Gio.Objects.Task.Task'\'s API attempts to be simpler than 'GI.Gio.Objects.SimpleAsyncResult.SimpleAsyncResult'\'s in several ways:
- You can save task-specific data with
taskSetTaskData
, and retrieve it later withtaskGetTaskData
. This replaces the abuse ofg_simple_async_result_set_op_res_gpointer()
for the same purpose withSimpleAsyncResult
. - In addition to the task data,
Task
also keeps track of the [priority][io-priority],Cancellable
, andMainContext
associated with the task, so tasks that consist of a chain of simpler asynchronous operations will have easy access to those values when starting each sub-task. taskReturnErrorIfCancelled
provides simplified handling for cancellation. In addition, cancellation overrides any otherTask
return value by default, likeSimpleAsyncResult
does whensimpleAsyncResultSetCheckCancellable
is called. (You can usetaskSetCheckCancellable
to turn off that behavior.) On the other hand,g_task_run_in_thread()
guarantees that it will always run yourtask_func
, even if the task'sCancellable
is already cancelled before the task gets a chance to run; you can start yourtask_func
with ataskReturnErrorIfCancelled
check if you need the old behavior.- The "return" methods (eg,
taskReturnPointer
) automatically cause the task to be "completed" as well, and there is no need to worry about the "complete" vs "complete in idle" distinction. (Task
automatically figures out whether the task's callback can be invoked directly, or if it needs to be sent to anotherMainContext
, or delayed until the next iteration of the currentMainContext
.) - The "finish" functions for
Task
based operations are generally much simpler thanSimpleAsyncResult
ones, normally consisting of only a single call totaskPropagatePointer
or the like. SincetaskPropagatePointer
"steals" the return value from theTask
, it is not necessary to juggle pointers around to prevent it from being freed twice. - With
SimpleAsyncResult
, it was common to callsimpleAsyncResultPropagateError
from the_finish()
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 appropriateg_task_propagate_
function. Note that wrapper methods can now useasyncResultLegacyPropagateError
to do old-styleSimpleAsyncResult
error-returning behavior, andasyncResultIsTagged
to check if a result is tagged as having come from the_async()
wrapper function (for "short-circuit" results, such as when passing 0 toinputStreamReadAsync
).
Synopsis
- newtype Task = Task (ManagedPtr Task)
- class GObject o => IsTask o
- toTask :: (MonadIO m, IsTask o) => o -> m Task
- noTask :: Maybe Task
- taskGetCancellable :: (HasCallStack, MonadIO m, IsTask a) => a -> m Cancellable
- taskGetCheckCancellable :: (HasCallStack, MonadIO m, IsTask a) => a -> m Bool
- taskGetCompleted :: (HasCallStack, MonadIO m, IsTask a) => a -> m Bool
- taskGetContext :: (HasCallStack, MonadIO m, IsTask a) => a -> m MainContext
- taskGetPriority :: (HasCallStack, MonadIO m, IsTask a) => a -> m Int32
- taskGetReturnOnCancel :: (HasCallStack, MonadIO m, IsTask a) => a -> m Bool
- taskGetSourceObject :: (HasCallStack, MonadIO m, IsTask a) => a -> m (Maybe Object)
- taskGetSourceTag :: (HasCallStack, MonadIO m, IsTask a) => a -> m (Ptr ())
- taskGetTaskData :: (HasCallStack, MonadIO m, IsTask a) => a -> m (Ptr ())
- taskHadError :: (HasCallStack, MonadIO m, IsTask a) => a -> m Bool
- taskIsValid :: (HasCallStack, MonadIO m, IsAsyncResult a, IsObject b) => a -> Maybe b -> m Bool
- taskNew :: (HasCallStack, MonadIO m, IsObject a, IsCancellable b) => Maybe a -> Maybe b -> Maybe AsyncReadyCallback -> m Task
- taskPropagateBoolean :: (HasCallStack, MonadIO m, IsTask a) => a -> m ()
- taskPropagateInt :: (HasCallStack, MonadIO m, IsTask a) => a -> m Int64
- taskPropagatePointer :: (HasCallStack, MonadIO m, IsTask a) => a -> m (Ptr ())
- taskReportError :: (HasCallStack, MonadIO m, IsObject a) => Maybe a -> Maybe AsyncReadyCallback -> Ptr () -> GError -> m ()
- taskReturnBoolean :: (HasCallStack, MonadIO m, IsTask a) => a -> Bool -> m ()
- taskReturnError :: (HasCallStack, MonadIO m, IsTask a) => a -> GError -> m ()
- taskReturnErrorIfCancelled :: (HasCallStack, MonadIO m, IsTask a) => a -> m Bool
- taskReturnInt :: (HasCallStack, MonadIO m, IsTask a) => a -> Int64 -> m ()
- taskReturnPointer :: (HasCallStack, MonadIO m, IsTask a) => a -> Ptr () -> Maybe DestroyNotify -> m ()
- taskSetCheckCancellable :: (HasCallStack, MonadIO m, IsTask a) => a -> Bool -> m ()
- taskSetPriority :: (HasCallStack, MonadIO m, IsTask a) => a -> Int32 -> m ()
- taskSetReturnOnCancel :: (HasCallStack, MonadIO m, IsTask a) => a -> Bool -> m Bool
- taskSetSourceTag :: (HasCallStack, MonadIO m, IsTask a) => a -> Ptr () -> m ()
- taskSetTaskData :: (HasCallStack, MonadIO m, IsTask a) => a -> Ptr () -> Maybe DestroyNotify -> m ()
- getTaskCompleted :: (MonadIO m, IsTask o) => o -> m Bool
Exported types
Memory-managed wrapper type.
Instances
GObject Task Source # | |
Defined in GI.Gio.Objects.Task gobjectType :: Task -> IO GType # | |
IsObject Task Source # | |
Defined in GI.Gio.Objects.Task | |
IsAsyncResult Task Source # | |
Defined in GI.Gio.Objects.Task | |
IsTask Task Source # | |
Defined in GI.Gio.Objects.Task |
class GObject o => IsTask o Source #
Instances
(GObject a, (UnknownAncestorError Task a :: Constraint)) => IsTask a Source # | |
Defined in GI.Gio.Objects.Task | |
IsTask Task Source # | |
Defined in GI.Gio.Objects.Task |
Methods
getCancellable
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m Cancellable | Returns: |
Gets task
's Cancellable
Since: 2.36
getCheckCancellable
taskGetCheckCancellable Source #
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m Bool |
Gets task
's check-cancellable flag. See
taskSetCheckCancellable
for more details.
Since: 2.36
getCompleted
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m Bool |
getContext
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m MainContext | Returns: |
Gets the MainContext
that task
will return its result in (that
is, the context that was the
[thread-default main context][g-main-context-push-thread-default]
at the point when task
was created).
This will always return a non-Nothing
value, even if the task's
context is the default MainContext
.
Since: 2.36
getPriority
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m Int32 | Returns: |
Gets task
's priority
Since: 2.36
getReturnOnCancel
taskGetReturnOnCancel Source #
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m Bool |
Gets task
's return-on-cancel flag. See
taskSetReturnOnCancel
for more details.
Since: 2.36
getSourceObject
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m (Maybe Object) | Returns: |
Gets the source object from task
. Like
asyncResultGetSourceObject
, but does not ref the object.
Since: 2.36
getSourceTag
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m (Ptr ()) | Returns: |
Gets task
's source tag. See taskSetSourceTag
.
Since: 2.36
getTaskData
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m (Ptr ()) | Returns: |
Gets task
's task_data
.
Since: 2.36
hadError
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m Bool | Returns: |
Tests if task
resulted in an error.
Since: 2.36
isValid
:: (HasCallStack, MonadIO m, IsAsyncResult a, IsObject b) | |
=> a |
|
-> Maybe b |
|
-> m Bool | Returns: |
new
:: (HasCallStack, MonadIO m, IsObject a, IsCancellable b) | |
=> Maybe a | |
-> Maybe b |
|
-> Maybe AsyncReadyCallback |
|
-> m Task | Returns: a |
Creates a Task
acting on sourceObject
, which will eventually be
used to invoke callback
in the current
[thread-default main context][g-main-context-push-thread-default].
Call this in the "start" method of your asynchronous method, and
pass the Task
around throughout the asynchronous operation. You
can use taskSetTaskData
to attach task-specific data to the
object, which you can retrieve later via taskGetTaskData
.
By default, if cancellable
is cancelled, then the return value of
the task will always be IOErrorEnumCancelled
, even if the task had
already completed before the cancellation. This allows for
simplified handling in cases where cancellation may imply that
other objects that the task depends on have been destroyed. If you
do not want this behavior, you can use
taskSetCheckCancellable
to change it.
Since: 2.36
propagateBoolean
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m () | (Can throw |
propagateInt
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m Int64 | Returns: the task result, or -1 on error (Can throw |
Gets the result of task
as an integer (gssize
).
If the task resulted in an error, or was cancelled, then this will
instead return -1 and set error
.
Since this method transfers ownership of the return value (or error) to the caller, you may only call it once.
Since: 2.36
propagatePointer
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m (Ptr ()) | Returns: the task result, or |
Gets the result of task
as a pointer, and transfers ownership
of that value to the caller.
If the task resulted in an error, or was cancelled, then this will
instead return Nothing
and set error
.
Since this method transfers ownership of the return value (or error) to the caller, you may only call it once.
Since: 2.36
reportError
:: (HasCallStack, MonadIO m, IsObject a) | |
=> Maybe a | |
-> Maybe AsyncReadyCallback |
|
-> Ptr () |
|
-> GError |
|
-> m () |
Creates a Task
and then immediately calls taskReturnError
on it. Use this in the wrapper function of an asynchronous method
when you want to avoid even calling the virtual method. You can
then use asyncResultIsTagged
in the finish method wrapper to
check if the result there is tagged as having been created by the
wrapper method, and deal with it appropriately if so.
See also g_task_report_new_error()
.
Since: 2.36
returnBoolean
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> Bool |
|
-> m () |
Sets task
's result to result
and completes the task (see
taskReturnPointer
for more discussion of exactly what this
means).
Since: 2.36
returnError
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> GError |
|
-> m () |
Sets task
's result to error
(which task
assumes ownership of)
and completes the task (see taskReturnPointer
for more
discussion of exactly what this means).
Note that since the task takes ownership of error
, and since the
task may be completed before returning from taskReturnError
,
you cannot assume that error
is still valid after calling this.
Call errorCopy
on the error if you need to keep a local copy
as well.
See also g_task_return_new_error()
.
Since: 2.36
returnErrorIfCancelled
taskReturnErrorIfCancelled Source #
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> m Bool |
Checks if task
's Cancellable
has been cancelled, and if so, sets
task
's error accordingly and completes the task (see
taskReturnPointer
for more discussion of exactly what this
means).
Since: 2.36
returnInt
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> Int64 |
|
-> m () |
Sets task
's result to result
and completes the task (see
taskReturnPointer
for more discussion of exactly what this
means).
Since: 2.36
returnPointer
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> Ptr () |
|
-> Maybe DestroyNotify |
|
-> m () |
Sets task
's result to result
and completes the task. If result
is not Nothing
, then resultDestroy
will be used to free result
if
the caller does not take ownership of it with
taskPropagatePointer
.
"Completes the task" means that for an ordinary asynchronous task
it will either invoke the task's callback, or else queue that
callback to be invoked in the proper MainContext
, or in the next
iteration of the current MainContext
. For a task run via
g_task_run_in_thread()
or g_task_run_in_thread_sync()
, calling this
method will save result
to be returned to the caller later, but
the task will not actually be completed until the TaskThreadFunc
exits.
Note that since the task may be completed before returning from
taskReturnPointer
, you cannot assume that result
is still
valid after calling this, unless you are still holding another
reference on it.
Since: 2.36
setCheckCancellable
taskSetCheckCancellable Source #
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> Bool |
|
-> m () |
Sets or clears task
's check-cancellable flag. If this is True
(the default), then taskPropagatePointer
, etc, and
taskHadError
will check the task's Cancellable
first, and
if it has been cancelled, then they will consider the task to have
returned an "Operation was cancelled" error
(IOErrorEnumCancelled
), regardless of any other error or return
value the task may have had.
If checkCancellable
is False
, then the Task
will not check the
cancellable itself, and it is up to task
's owner to do this (eg,
via taskReturnErrorIfCancelled
).
If you are using taskSetReturnOnCancel
as well, then
you must leave check-cancellable set True
.
Since: 2.36
setPriority
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> Int32 |
|
-> m () |
Sets task
's priority. If you do not call this, it will default to
PRIORITY_DEFAULT
.
This will affect the priority of GSources
created with
g_task_attach_source()
and the scheduling of tasks run in threads,
and can also be explicitly retrieved later via
taskGetPriority
.
Since: 2.36
setReturnOnCancel
taskSetReturnOnCancel Source #
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> Bool |
|
-> m Bool | Returns: |
Sets or clears task
's return-on-cancel flag. This is only
meaningful for tasks run via g_task_run_in_thread()
or
g_task_run_in_thread_sync()
.
If returnOnCancel
is True
, then cancelling task
's
Cancellable
will immediately cause it to return, as though the
task's TaskThreadFunc
had called
taskReturnErrorIfCancelled
and then returned.
This allows you to create a cancellable wrapper around an
uninterruptable function. The TaskThreadFunc
just needs to be
careful that it does not modify any externally-visible state after
it has been cancelled. To do that, the thread should call
taskSetReturnOnCancel
again to (atomically) set
return-on-cancel False
before making externally-visible changes;
if the task gets cancelled before the return-on-cancel flag could
be changed, taskSetReturnOnCancel
will indicate this by
returning False
.
You can disable and re-enable this flag multiple times if you wish.
If the task's Cancellable
is cancelled while return-on-cancel is
False
, then calling taskSetReturnOnCancel
to set it True
again will cause the task to be cancelled at that point.
If the task's Cancellable
is already cancelled before you call
g_task_run_in_thread()
/g_task_run_in_thread_sync()
, then the
TaskThreadFunc
will still be run (for consistency), but the task
will also be completed right away.
Since: 2.36
setSourceTag
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> Ptr () |
|
-> m () |
Sets task
's source tag. You can use this to tag a task return
value with a particular pointer (usually a pointer to the function
doing the tagging) and then later check it using
taskGetSourceTag
(or asyncResultIsTagged
) in the
task's "finish" function, to figure out if the response came from a
particular place.
Since: 2.36
setTaskData
:: (HasCallStack, MonadIO m, IsTask a) | |
=> a |
|
-> Ptr () |
|
-> Maybe DestroyNotify |
|
-> m () |
Sets task
's task data (freeing the existing task data, if any).
Since: 2.36
Properties
completed
Whether the task has completed, meaning its callback (if set) has been
invoked. This can only happen after taskReturnPointer
,
taskReturnError
or one of the other return functions have been called
on the task.
This property is guaranteed to change from False
to True
exactly once.
The Object
::notify
signal for this change is emitted in the same main
context as the task’s callback, immediately after that callback is invoked.
Since: 2.44
getTaskCompleted :: (MonadIO m, IsTask o) => o -> m Bool Source #
Get the value of the “completed
” property.
When overloading is enabled, this is equivalent to
get
task #completed