diff --git a/include/io/task.h b/include/io/task.h index ece1372781..47daba961b 100644 --- a/include/io/task.h +++ b/include/io/task.h @@ -239,6 +239,38 @@ void qio_task_abort(QIOTask *task, Error *err); +/** + * qio_task_set_error: + * @task: the task struct + * @err: pointer to the error, or NULL + * + * Associate an error with the task, which can later + * be retrieved with the qio_task_propagate_error() + * method. This method takes ownership of @err, so + * it is not valid to access it after this call + * completes. If @err is NULL this is a no-op. If + * this is call multiple times, only the first + * provided @err will be recorded, later ones will + * be discarded and freed. + */ +void qio_task_set_error(QIOTask *task, + Error *err); + + +/** + * qio_task_propagate_error: + * @task: the task struct + * @errp: pointer to a NULL-initialized error object + * + * Propagate the error associated with @task + * into @errp. + * + * Returns: true if an error was propagated, false otherwise + */ +bool qio_task_propagate_error(QIOTask *task, + Error **errp); + + /** * qio_task_set_result_pointer: * @task: the task struct diff --git a/io/task.c b/io/task.c index 675e196156..1394e05200 100644 --- a/io/task.c +++ b/io/task.c @@ -29,6 +29,7 @@ struct QIOTask { QIOTaskFunc func; gpointer opaque; GDestroyNotify destroy; + Error *err; gpointer result; GDestroyNotify destroyResult; }; @@ -62,6 +63,9 @@ static void qio_task_free(QIOTask *task) if (task->destroyResult) { task->destroyResult(task->result); } + if (task->err) { + error_free(task->err); + } object_unref(task->source); g_free(task); @@ -159,6 +163,25 @@ void qio_task_abort(QIOTask *task, } +void qio_task_set_error(QIOTask *task, + Error *err) +{ + error_propagate(&task->err, err); +} + + +bool qio_task_propagate_error(QIOTask *task, + Error **errp) +{ + if (task->err) { + error_propagate(errp, task->err); + return true; + } + + return false; +} + + void qio_task_set_result_pointer(QIOTask *task, gpointer result, GDestroyNotify destroy)