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