| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * QEMU I/O task | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2015 Red Hat, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2020-10-14 13:40:33 +00:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-29 13:47:03 +02:00
										 |  |  | #ifndef QIO_TASK_H
 | 
					
						
							|  |  |  | #define QIO_TASK_H
 | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct QIOTask QIOTask; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  | typedef void (*QIOTaskFunc)(QIOTask *task, | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |                             gpointer opaque); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-11 17:38:07 +01:00
										 |  |  | typedef void (*QIOTaskWorker)(QIOTask *task, | 
					
						
							|  |  |  |                               gpointer opaque); | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * QIOTask: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The QIOTask object provides a simple mechanism for reporting | 
					
						
							|  |  |  |  * success / failure of long running background operations. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A object on which the operation is to be performed could have | 
					
						
							|  |  |  |  * a public API which accepts a task callback: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * <example> | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  |  *   <title>Task function signature</title> | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *   <programlisting> | 
					
						
							|  |  |  |  *  void myobject_operation(QMyObject *obj, | 
					
						
							|  |  |  |  *                          QIOTaskFunc *func, | 
					
						
							|  |  |  |  *                          gpointer opaque, | 
					
						
							| 
									
										
										
										
											2016-08-11 14:25:30 +01:00
										 |  |  |  *                          GDestroyNotify notify); | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *   </programlisting> | 
					
						
							|  |  |  |  * </example> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The 'func' parameter is the callback to be invoked, and 'opaque' | 
					
						
							|  |  |  |  * is data to pass to it. The optional 'notify' function is used | 
					
						
							|  |  |  |  * to free 'opaque' when no longer needed. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  |  * When the operation completes, the 'func' callback will be | 
					
						
							|  |  |  |  * invoked, allowing the calling code to determine the result | 
					
						
							|  |  |  |  * of the operation. An example QIOTaskFunc implementation may | 
					
						
							|  |  |  |  * look like | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * <example> | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  |  *   <title>Task callback implementation</title> | 
					
						
							|  |  |  |  *   <programlisting> | 
					
						
							|  |  |  |  *  static void myobject_operation_notify(QIOTask *task, | 
					
						
							|  |  |  |  *                                        gpointer opaque) | 
					
						
							|  |  |  |  *  { | 
					
						
							|  |  |  |  *      Error *err = NULL; | 
					
						
							|  |  |  |  *      if (qio_task_propagate_error(task, &err)) { | 
					
						
							|  |  |  |  *          ...deal with the failure... | 
					
						
							|  |  |  |  *          error_free(err); | 
					
						
							|  |  |  |  *      } else { | 
					
						
							|  |  |  |  *          QMyObject *src = QMY_OBJECT(qio_task_get_source(task)); | 
					
						
							|  |  |  |  *          ...deal with the completion... | 
					
						
							|  |  |  |  *      } | 
					
						
							|  |  |  |  *  } | 
					
						
							|  |  |  |  *   </programlisting> | 
					
						
							|  |  |  |  * </example> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Now, lets say the implementation of the method using the | 
					
						
							|  |  |  |  * task wants to set a timer to run once a second checking | 
					
						
							|  |  |  |  * for completion of some activity. It would do something | 
					
						
							|  |  |  |  * like | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * <example> | 
					
						
							|  |  |  |  *   <title>Task function implementation</title> | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *   <programlisting> | 
					
						
							|  |  |  |  *    void myobject_operation(QMyObject *obj, | 
					
						
							|  |  |  |  *                            QIOTaskFunc *func, | 
					
						
							|  |  |  |  *                            gpointer opaque, | 
					
						
							| 
									
										
										
										
											2016-08-11 14:25:30 +01:00
										 |  |  |  *                            GDestroyNotify notify) | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *    { | 
					
						
							|  |  |  |  *      QIOTask *task; | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *      task = qio_task_new(OBJECT(obj), func, opaque, notify); | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *      g_timeout_add_full(G_PRIORITY_DEFAULT, | 
					
						
							|  |  |  |  *                         1000, | 
					
						
							|  |  |  |  *                         myobject_operation_timer, | 
					
						
							|  |  |  |  *                         task, | 
					
						
							|  |  |  |  *                         NULL); | 
					
						
							|  |  |  |  *    } | 
					
						
							|  |  |  |  *   </programlisting> | 
					
						
							|  |  |  |  * </example> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * It could equally have setup a watch on a file descriptor or | 
					
						
							|  |  |  |  * created a background thread, or something else entirely. | 
					
						
							|  |  |  |  * Notice that the source object is passed to the task, and | 
					
						
							|  |  |  |  * QIOTask will hold a reference on that. This ensure that | 
					
						
							|  |  |  |  * the QMyObject instance cannot be garbage collected while | 
					
						
							|  |  |  |  * the async task is still in progress. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * In this case, myobject_operation_timer will fire after | 
					
						
							|  |  |  |  * 3 secs and do | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * <example> | 
					
						
							|  |  |  |  *   <title>Task timer function</title> | 
					
						
							|  |  |  |  *   <programlisting> | 
					
						
							|  |  |  |  *   gboolean myobject_operation_timer(gpointer opaque) | 
					
						
							|  |  |  |  *   { | 
					
						
							|  |  |  |  *      QIOTask *task = QIO_TASK(opaque); | 
					
						
							| 
									
										
										
										
											2019-12-04 10:36:10 +01:00
										 |  |  |  *      Error *err = NULL; | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *      ...check something important... | 
					
						
							|  |  |  |  *       if (err) { | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  |  *           qio_task_set_error(task, err); | 
					
						
							|  |  |  |  *           qio_task_complete(task); | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *           return FALSE; | 
					
						
							|  |  |  |  *       } else if (...work is completed ...) { | 
					
						
							|  |  |  |  *           qio_task_complete(task); | 
					
						
							|  |  |  |  *           return FALSE; | 
					
						
							|  |  |  |  *       } | 
					
						
							|  |  |  |  *       ...carry on polling ... | 
					
						
							|  |  |  |  *       return TRUE; | 
					
						
							|  |  |  |  *   } | 
					
						
							|  |  |  |  *   </programlisting> | 
					
						
							|  |  |  |  * </example> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  |  * The 'qio_task_complete' call in this method will trigger | 
					
						
							|  |  |  |  * the callback func 'myobject_operation_notify' shown | 
					
						
							|  |  |  |  * earlier to deal with the results. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * Once this function returns false, object_unref will be called | 
					
						
							|  |  |  |  * automatically on the task causing it to be released and the | 
					
						
							|  |  |  |  * ref on QMyObject dropped too. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The QIOTask module can also be used to perform operations | 
					
						
							|  |  |  |  * in a background thread context, while still reporting the | 
					
						
							|  |  |  |  * results in the main event thread. This allows code which | 
					
						
							| 
									
										
										
										
											2023-08-23 09:53:15 +03:00
										 |  |  |  * cannot easily be rewritten to be asynchronous (such as DNS | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * lookups) to be easily run non-blocking. Reporting the | 
					
						
							|  |  |  |  * results in the main thread context means that the caller | 
					
						
							|  |  |  |  * typically does not need to be concerned about thread | 
					
						
							|  |  |  |  * safety wrt the QEMU global mutex. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * For example, the socket_listen() method will block the caller | 
					
						
							|  |  |  |  * while DNS lookups take place if given a name, instead of IP | 
					
						
							|  |  |  |  * address. The C library often do not provide a practical async | 
					
						
							|  |  |  |  * DNS API, so the to get non-blocking DNS lookups in a portable | 
					
						
							|  |  |  |  * manner requires use of a thread. So achieve a non-blocking | 
					
						
							|  |  |  |  * socket listen using QIOTask would require: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * <example> | 
					
						
							| 
									
										
										
										
											2016-08-11 17:38:07 +01:00
										 |  |  |  *    static void myobject_listen_worker(QIOTask *task, | 
					
						
							|  |  |  |  *                                       gpointer opaque) | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *    { | 
					
						
							|  |  |  |  *       QMyObject obj = QMY_OBJECT(qio_task_get_source(task)); | 
					
						
							|  |  |  |  *       SocketAddress *addr = opaque; | 
					
						
							| 
									
										
										
										
											2016-08-11 17:38:07 +01:00
										 |  |  |  *       Error *err = NULL; | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-08-11 17:38:07 +01:00
										 |  |  |  *       obj->fd = socket_listen(addr, &err); | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |          qio_task_set_error(task, err); | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *    } | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *    void myobject_listen_async(QMyObject *obj, | 
					
						
							|  |  |  |  *                               SocketAddress *addr, | 
					
						
							|  |  |  |  *                               QIOTaskFunc *func, | 
					
						
							|  |  |  |  *                               gpointer opaque, | 
					
						
							| 
									
										
										
										
											2016-08-11 14:25:30 +01:00
										 |  |  |  *                               GDestroyNotify notify) | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *    { | 
					
						
							|  |  |  |  *      QIOTask *task; | 
					
						
							|  |  |  |  *      SocketAddress *addrCopy; | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-06-09 10:48:45 -06:00
										 |  |  |  *      addrCopy = QAPI_CLONE(SocketAddress, addr); | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  *      task = qio_task_new(OBJECT(obj), func, opaque, notify); | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *      qio_task_run_in_thread(task, myobject_listen_worker, | 
					
						
							|  |  |  |  *                             addrCopy, | 
					
						
							|  |  |  |  *                             qapi_free_SocketAddress); | 
					
						
							|  |  |  |  *    } | 
					
						
							|  |  |  |  * </example> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * NB, The 'func' callback passed into myobject_listen_async | 
					
						
							|  |  |  |  * will be invoked from the main event thread, despite the | 
					
						
							|  |  |  |  * actual operation being performed in a different thread. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * qio_task_new: | 
					
						
							|  |  |  |  * @source: the object on which the operation is invoked | 
					
						
							|  |  |  |  * @func: the callback to invoke when the task completes | 
					
						
							|  |  |  |  * @opaque: opaque data to pass to @func when invoked | 
					
						
							|  |  |  |  * @destroy: optional callback to free @opaque | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Creates a new task struct to track completion of a | 
					
						
							|  |  |  |  * background operation running on the object @source. | 
					
						
							|  |  |  |  * When the operation completes or fails, the callback | 
					
						
							|  |  |  |  * @func will be invoked. The callback can access the | 
					
						
							|  |  |  |  * 'err' attribute in the task object to determine if | 
					
						
							|  |  |  |  * the operation was successful or not. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  |  * The returned task will be released when qio_task_complete() | 
					
						
							|  |  |  |  * is invoked. | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Returns: the task struct | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | QIOTask *qio_task_new(Object *source, | 
					
						
							|  |  |  |                       QIOTaskFunc func, | 
					
						
							|  |  |  |                       gpointer opaque, | 
					
						
							|  |  |  |                       GDestroyNotify destroy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * qio_task_run_in_thread: | 
					
						
							|  |  |  |  * @task: the task struct | 
					
						
							|  |  |  |  * @worker: the function to invoke in a thread | 
					
						
							|  |  |  |  * @opaque: opaque data to pass to @worker | 
					
						
							|  |  |  |  * @destroy: function to free @opaque | 
					
						
							| 
									
										
										
										
											2018-03-05 14:43:22 +08:00
										 |  |  |  * @context: the context to run the complete hook. If %NULL, the | 
					
						
							|  |  |  |  *           default context will be used. | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  |  * Run a task in a background thread. When @worker | 
					
						
							|  |  |  |  * returns it will call qio_task_complete() in | 
					
						
							| 
									
										
										
										
											2019-02-11 18:24:28 +00:00
										 |  |  |  * the thread that is running the main loop associated | 
					
						
							|  |  |  |  * with @context. | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | void qio_task_run_in_thread(QIOTask *task, | 
					
						
							|  |  |  |                             QIOTaskWorker worker, | 
					
						
							|  |  |  |                             gpointer opaque, | 
					
						
							| 
									
										
										
										
											2018-03-05 14:43:22 +08:00
										 |  |  |                             GDestroyNotify destroy, | 
					
						
							|  |  |  |                             GMainContext *context); | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-11 18:24:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * qio_task_wait_thread: | 
					
						
							|  |  |  |  * @task: the task struct | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Wait for completion of a task that was previously | 
					
						
							|  |  |  |  * invoked using qio_task_run_in_thread. This MUST | 
					
						
							|  |  |  |  * ONLY be invoked if the task has not already | 
					
						
							|  |  |  |  * completed, since after the completion callback | 
					
						
							|  |  |  |  * is invoked, @task will have been freed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * To avoid racing with execution of the completion | 
					
						
							|  |  |  |  * callback provided with qio_task_new, this method | 
					
						
							|  |  |  |  * MUST ONLY be invoked from the thread that is | 
					
						
							|  |  |  |  * running the main loop associated with @context | 
					
						
							|  |  |  |  * parameter to qio_task_run_in_thread. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * When the thread has completed, the completion | 
					
						
							|  |  |  |  * callback provided to qio_task_new will be invoked. | 
					
						
							|  |  |  |  * When that callback returns @task will be freed, | 
					
						
							|  |  |  |  * so @task must not be referenced after this | 
					
						
							|  |  |  |  * method completes. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void qio_task_wait_thread(QIOTask *task); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * qio_task_complete: | 
					
						
							|  |  |  |  * @task: the task struct | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-08-11 15:20:58 +01:00
										 |  |  |  * Invoke the completion callback for @task and | 
					
						
							|  |  |  |  * then free its memory. | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | void qio_task_complete(QIOTask *task); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-11 14:40:44 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * 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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-11 14:36:21 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * qio_task_set_result_pointer: | 
					
						
							|  |  |  |  * @task: the task struct | 
					
						
							|  |  |  |  * @result: pointer to the result data | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Associate an opaque result with the task, | 
					
						
							|  |  |  |  * which can later be retrieved with the | 
					
						
							|  |  |  |  * qio_task_get_result_pointer() method | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void qio_task_set_result_pointer(QIOTask *task, | 
					
						
							|  |  |  |                                  gpointer result, | 
					
						
							|  |  |  |                                  GDestroyNotify notify); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * qio_task_get_result_pointer: | 
					
						
							|  |  |  |  * @task: the task struct | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Retrieve the opaque result data associated | 
					
						
							|  |  |  |  * with the task, if any. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: the task result, or NULL | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | gpointer qio_task_get_result_pointer(QIOTask *task); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * qio_task_get_source: | 
					
						
							|  |  |  |  * @task: the task struct | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Get the source object associated with the background | 
					
						
							| 
									
										
										
										
											2016-08-11 18:11:04 +01:00
										 |  |  |  * task. The caller does not own a reference on the | 
					
						
							|  |  |  |  * returned Object, and so should call object_ref() | 
					
						
							|  |  |  |  * if it wants to keep the object pointer outside the | 
					
						
							|  |  |  |  * lifetime of the QIOTask object. | 
					
						
							| 
									
										
										
										
											2015-03-18 17:25:45 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Returns: the source object | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | Object *qio_task_get_source(QIOTask *task); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-29 13:47:03 +02:00
										 |  |  | #endif /* QIO_TASK_H */
 |