qemu/include/qapi/qmp/qobject.h
<<
>>
Prefs
   1/*
   2 * QEMU Object Model.
   3 *
   4 * Based on ideas by Avi Kivity <avi@redhat.com>
   5 *
   6 * Copyright (C) 2009, 2015 Red Hat Inc.
   7 *
   8 * Authors:
   9 *  Luiz Capitulino <lcapitulino@redhat.com>
  10 *
  11 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
  12 * See the COPYING.LIB file in the top-level directory.
  13 *
  14 * QObject Reference Counts Terminology
  15 * ------------------------------------
  16 *
  17 *  - Returning references: A function that returns an object may
  18 *  return it as either a weak or a strong reference.  If the
  19 *  reference is strong, you are responsible for calling
  20 *  qobject_unref() on the reference when you are done.
  21 *
  22 *  If the reference is weak, the owner of the reference may free it at
  23 *  any time in the future.  Before storing the reference anywhere, you
  24 *  should call qobject_ref() to make the reference strong.
  25 *
  26 *  - Transferring ownership: when you transfer ownership of a reference
  27 *  by calling a function, you are no longer responsible for calling
  28 *  qobject_unref() when the reference is no longer needed.  In other words,
  29 *  when the function returns you must behave as if the reference to the
  30 *  passed object was weak.
  31 */
  32#ifndef QOBJECT_H
  33#define QOBJECT_H
  34
  35#include "qapi/qapi-builtin-types.h"
  36
  37/* Not for use outside include/qapi/qmp/ */
  38struct QObjectBase_ {
  39    QType type;
  40    size_t refcnt;
  41};
  42
  43/* this struct must have no other members than base */
  44struct QObject {
  45    struct QObjectBase_ base;
  46};
  47
  48#define QOBJECT(obj) ({                                         \
  49    typeof(obj) _obj = (obj);                                   \
  50    _obj ? container_of(&(_obj)->base, QObject, base) : NULL;   \
  51})
  52
  53/* Required for qobject_to() */
  54#define QTYPE_CAST_TO_QNull     QTYPE_QNULL
  55#define QTYPE_CAST_TO_QNum      QTYPE_QNUM
  56#define QTYPE_CAST_TO_QString   QTYPE_QSTRING
  57#define QTYPE_CAST_TO_QDict     QTYPE_QDICT
  58#define QTYPE_CAST_TO_QList     QTYPE_QLIST
  59#define QTYPE_CAST_TO_QBool     QTYPE_QBOOL
  60
  61QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7,
  62                   "The QTYPE_CAST_TO_* list needs to be extended");
  63
  64#define qobject_to(type, obj)                                       \
  65    ((type *)qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)))
  66
  67/* Initialize an object to default values */
  68static inline void qobject_init(QObject *obj, QType type)
  69{
  70    assert(QTYPE_NONE < type && type < QTYPE__MAX);
  71    obj->base.refcnt = 1;
  72    obj->base.type = type;
  73}
  74
  75static inline void qobject_ref_impl(QObject *obj)
  76{
  77    if (obj) {
  78        obj->base.refcnt++;
  79    }
  80}
  81
  82/**
  83 * qobject_is_equal(): Return whether the two objects are equal.
  84 *
  85 * Any of the pointers may be NULL; return true if both are.  Always
  86 * return false if only one is (therefore a QNull object is not
  87 * considered equal to a NULL pointer).
  88 */
  89bool qobject_is_equal(const QObject *x, const QObject *y);
  90
  91/**
  92 * qobject_destroy(): Free resources used by the object
  93 */
  94void qobject_destroy(QObject *obj);
  95
  96static inline void qobject_unref_impl(QObject *obj)
  97{
  98    assert(!obj || obj->base.refcnt);
  99    if (obj && --obj->base.refcnt == 0) {
 100        qobject_destroy(obj);
 101    }
 102}
 103
 104/**
 105 * qobject_ref(): Increment QObject's reference count
 106 *
 107 * Returns: the same @obj. The type of @obj will be propagated to the
 108 * return type.
 109 */
 110#define qobject_ref(obj) ({                     \
 111    typeof(obj) _o = (obj);                     \
 112    qobject_ref_impl(QOBJECT(_o));              \
 113    _o;                                         \
 114})
 115
 116/**
 117 * qobject_unref(): Decrement QObject's reference count, deallocate
 118 * when it reaches zero
 119 */
 120#define qobject_unref(obj) qobject_unref_impl(QOBJECT(obj))
 121
 122/**
 123 * qobject_type(): Return the QObject's type
 124 */
 125static inline QType qobject_type(const QObject *obj)
 126{
 127    assert(QTYPE_NONE < obj->base.type && obj->base.type < QTYPE__MAX);
 128    return obj->base.type;
 129}
 130
 131/**
 132 * qobject_check_type(): Helper function for the qobject_to() macro.
 133 * Return @obj, but only if @obj is not NULL and @type is equal to
 134 * @obj's type.  Return NULL otherwise.
 135 */
 136static inline QObject *qobject_check_type(const QObject *obj, QType type)
 137{
 138    if (obj && qobject_type(obj) == type) {
 139        return (QObject *)obj;
 140    } else {
 141        return NULL;
 142    }
 143}
 144
 145#endif /* QOBJECT_H */
 146