task.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * QEMU I/O task
  3. *
  4. * Copyright (c) 2015 Red Hat, Inc.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. #ifndef QIO_TASK_H
  21. #define QIO_TASK_H
  22. typedef struct QIOTask QIOTask;
  23. typedef void (*QIOTaskFunc)(QIOTask *task,
  24. gpointer opaque);
  25. typedef void (*QIOTaskWorker)(QIOTask *task,
  26. gpointer opaque);
  27. /**
  28. * QIOTask:
  29. *
  30. * The QIOTask object provides a simple mechanism for reporting
  31. * success / failure of long running background operations.
  32. *
  33. * A object on which the operation is to be performed could have
  34. * a public API which accepts a task callback:
  35. *
  36. * <example>
  37. * <title>Task function signature</title>
  38. * <programlisting>
  39. * void myobject_operation(QMyObject *obj,
  40. * QIOTaskFunc *func,
  41. * gpointer opaque,
  42. * GDestroyNotify notify);
  43. * </programlisting>
  44. * </example>
  45. *
  46. * The 'func' parameter is the callback to be invoked, and 'opaque'
  47. * is data to pass to it. The optional 'notify' function is used
  48. * to free 'opaque' when no longer needed.
  49. *
  50. * When the operation completes, the 'func' callback will be
  51. * invoked, allowing the calling code to determine the result
  52. * of the operation. An example QIOTaskFunc implementation may
  53. * look like
  54. *
  55. * <example>
  56. * <title>Task callback implementation</title>
  57. * <programlisting>
  58. * static void myobject_operation_notify(QIOTask *task,
  59. * gpointer opaque)
  60. * {
  61. * Error *err = NULL;
  62. * if (qio_task_propagate_error(task, &err)) {
  63. * ...deal with the failure...
  64. * error_free(err);
  65. * } else {
  66. * QMyObject *src = QMY_OBJECT(qio_task_get_source(task));
  67. * ...deal with the completion...
  68. * }
  69. * }
  70. * </programlisting>
  71. * </example>
  72. *
  73. * Now, lets say the implementation of the method using the
  74. * task wants to set a timer to run once a second checking
  75. * for completion of some activity. It would do something
  76. * like
  77. *
  78. * <example>
  79. * <title>Task function implementation</title>
  80. * <programlisting>
  81. * void myobject_operation(QMyObject *obj,
  82. * QIOTaskFunc *func,
  83. * gpointer opaque,
  84. * GDestroyNotify notify)
  85. * {
  86. * QIOTask *task;
  87. *
  88. * task = qio_task_new(OBJECT(obj), func, opaque, notify);
  89. *
  90. * g_timeout_add_full(G_PRIORITY_DEFAULT,
  91. * 1000,
  92. * myobject_operation_timer,
  93. * task,
  94. * NULL);
  95. * }
  96. * </programlisting>
  97. * </example>
  98. *
  99. * It could equally have setup a watch on a file descriptor or
  100. * created a background thread, or something else entirely.
  101. * Notice that the source object is passed to the task, and
  102. * QIOTask will hold a reference on that. This ensure that
  103. * the QMyObject instance cannot be garbage collected while
  104. * the async task is still in progress.
  105. *
  106. * In this case, myobject_operation_timer will fire after
  107. * 3 secs and do
  108. *
  109. * <example>
  110. * <title>Task timer function</title>
  111. * <programlisting>
  112. * gboolean myobject_operation_timer(gpointer opaque)
  113. * {
  114. * QIOTask *task = QIO_TASK(opaque);
  115. * Error *err = NULL;
  116. *
  117. * ...check something important...
  118. * if (err) {
  119. * qio_task_set_error(task, err);
  120. * qio_task_complete(task);
  121. * return FALSE;
  122. * } else if (...work is completed ...) {
  123. * qio_task_complete(task);
  124. * return FALSE;
  125. * }
  126. * ...carry on polling ...
  127. * return TRUE;
  128. * }
  129. * </programlisting>
  130. * </example>
  131. *
  132. * The 'qio_task_complete' call in this method will trigger
  133. * the callback func 'myobject_operation_notify' shown
  134. * earlier to deal with the results.
  135. *
  136. * Once this function returns false, object_unref will be called
  137. * automatically on the task causing it to be released and the
  138. * ref on QMyObject dropped too.
  139. *
  140. * The QIOTask module can also be used to perform operations
  141. * in a background thread context, while still reporting the
  142. * results in the main event thread. This allows code which
  143. * cannot easily be rewritten to be asynchronous (such as DNS
  144. * lookups) to be easily run non-blocking. Reporting the
  145. * results in the main thread context means that the caller
  146. * typically does not need to be concerned about thread
  147. * safety wrt the QEMU global mutex.
  148. *
  149. * For example, the socket_listen() method will block the caller
  150. * while DNS lookups take place if given a name, instead of IP
  151. * address. The C library often do not provide a practical async
  152. * DNS API, so the to get non-blocking DNS lookups in a portable
  153. * manner requires use of a thread. So achieve a non-blocking
  154. * socket listen using QIOTask would require:
  155. *
  156. * <example>
  157. * static void myobject_listen_worker(QIOTask *task,
  158. * gpointer opaque)
  159. * {
  160. * QMyObject obj = QMY_OBJECT(qio_task_get_source(task));
  161. * SocketAddress *addr = opaque;
  162. * Error *err = NULL;
  163. *
  164. * obj->fd = socket_listen(addr, &err);
  165. *
  166. qio_task_set_error(task, err);
  167. * }
  168. *
  169. * void myobject_listen_async(QMyObject *obj,
  170. * SocketAddress *addr,
  171. * QIOTaskFunc *func,
  172. * gpointer opaque,
  173. * GDestroyNotify notify)
  174. * {
  175. * QIOTask *task;
  176. * SocketAddress *addrCopy;
  177. *
  178. * addrCopy = QAPI_CLONE(SocketAddress, addr);
  179. * task = qio_task_new(OBJECT(obj), func, opaque, notify);
  180. *
  181. * qio_task_run_in_thread(task, myobject_listen_worker,
  182. * addrCopy,
  183. * qapi_free_SocketAddress);
  184. * }
  185. * </example>
  186. *
  187. * NB, The 'func' callback passed into myobject_listen_async
  188. * will be invoked from the main event thread, despite the
  189. * actual operation being performed in a different thread.
  190. */
  191. /**
  192. * qio_task_new:
  193. * @source: the object on which the operation is invoked
  194. * @func: the callback to invoke when the task completes
  195. * @opaque: opaque data to pass to @func when invoked
  196. * @destroy: optional callback to free @opaque
  197. *
  198. * Creates a new task struct to track completion of a
  199. * background operation running on the object @source.
  200. * When the operation completes or fails, the callback
  201. * @func will be invoked. The callback can access the
  202. * 'err' attribute in the task object to determine if
  203. * the operation was successful or not.
  204. *
  205. * The returned task will be released when qio_task_complete()
  206. * is invoked.
  207. *
  208. * Returns: the task struct
  209. */
  210. QIOTask *qio_task_new(Object *source,
  211. QIOTaskFunc func,
  212. gpointer opaque,
  213. GDestroyNotify destroy);
  214. /**
  215. * qio_task_run_in_thread:
  216. * @task: the task struct
  217. * @worker: the function to invoke in a thread
  218. * @opaque: opaque data to pass to @worker
  219. * @destroy: function to free @opaque
  220. * @context: the context to run the complete hook. If %NULL, the
  221. * default context will be used.
  222. *
  223. * Run a task in a background thread. When @worker
  224. * returns it will call qio_task_complete() in
  225. * the thread that is running the main loop associated
  226. * with @context.
  227. */
  228. void qio_task_run_in_thread(QIOTask *task,
  229. QIOTaskWorker worker,
  230. gpointer opaque,
  231. GDestroyNotify destroy,
  232. GMainContext *context);
  233. /**
  234. * qio_task_wait_thread:
  235. * @task: the task struct
  236. *
  237. * Wait for completion of a task that was previously
  238. * invoked using qio_task_run_in_thread. This MUST
  239. * ONLY be invoked if the task has not already
  240. * completed, since after the completion callback
  241. * is invoked, @task will have been freed.
  242. *
  243. * To avoid racing with execution of the completion
  244. * callback provided with qio_task_new, this method
  245. * MUST ONLY be invoked from the thread that is
  246. * running the main loop associated with @context
  247. * parameter to qio_task_run_in_thread.
  248. *
  249. * When the thread has completed, the completion
  250. * callback provided to qio_task_new will be invoked.
  251. * When that callback returns @task will be freed,
  252. * so @task must not be referenced after this
  253. * method completes.
  254. */
  255. void qio_task_wait_thread(QIOTask *task);
  256. /**
  257. * qio_task_complete:
  258. * @task: the task struct
  259. *
  260. * Invoke the completion callback for @task and
  261. * then free its memory.
  262. */
  263. void qio_task_complete(QIOTask *task);
  264. /**
  265. * qio_task_set_error:
  266. * @task: the task struct
  267. * @err: pointer to the error, or NULL
  268. *
  269. * Associate an error with the task, which can later
  270. * be retrieved with the qio_task_propagate_error()
  271. * method. This method takes ownership of @err, so
  272. * it is not valid to access it after this call
  273. * completes. If @err is NULL this is a no-op. If
  274. * this is call multiple times, only the first
  275. * provided @err will be recorded, later ones will
  276. * be discarded and freed.
  277. */
  278. void qio_task_set_error(QIOTask *task,
  279. Error *err);
  280. /**
  281. * qio_task_propagate_error:
  282. * @task: the task struct
  283. * @errp: pointer to a NULL-initialized error object
  284. *
  285. * Propagate the error associated with @task
  286. * into @errp.
  287. *
  288. * Returns: true if an error was propagated, false otherwise
  289. */
  290. bool qio_task_propagate_error(QIOTask *task,
  291. Error **errp);
  292. /**
  293. * qio_task_set_result_pointer:
  294. * @task: the task struct
  295. * @result: pointer to the result data
  296. *
  297. * Associate an opaque result with the task,
  298. * which can later be retrieved with the
  299. * qio_task_get_result_pointer() method
  300. *
  301. */
  302. void qio_task_set_result_pointer(QIOTask *task,
  303. gpointer result,
  304. GDestroyNotify notify);
  305. /**
  306. * qio_task_get_result_pointer:
  307. * @task: the task struct
  308. *
  309. * Retrieve the opaque result data associated
  310. * with the task, if any.
  311. *
  312. * Returns: the task result, or NULL
  313. */
  314. gpointer qio_task_get_result_pointer(QIOTask *task);
  315. /**
  316. * qio_task_get_source:
  317. * @task: the task struct
  318. *
  319. * Get the source object associated with the background
  320. * task. The caller does not own a reference on the
  321. * returned Object, and so should call object_ref()
  322. * if it wants to keep the object pointer outside the
  323. * lifetime of the QIOTask object.
  324. *
  325. * Returns: the source object
  326. */
  327. Object *qio_task_get_source(QIOTask *task);
  328. #endif /* QIO_TASK_H */