cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

task.h (11125B)


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