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 reference
  19 *  is strong, you are responsible for calling QDECREF() on the reference
  20 *  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 QINCREF() 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 *  QDECREF() 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
  37struct QObject {
  38    QType type;
  39    size_t refcnt;
  40};
  41
  42/* Get the 'base' part of an object */
  43#define QOBJECT(obj) (&(obj)->base)
  44
  45/* High-level interface for qobject_incref() */
  46#define QINCREF(obj)      \
  47    qobject_incref(QOBJECT(obj))
  48
  49/* High-level interface for qobject_decref() */
  50#define QDECREF(obj)              \
  51    qobject_decref(obj ? QOBJECT(obj) : NULL)
  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    QObject *_tmp = qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)); \
  66    _tmp ? container_of(_tmp, type, base) : (type *)NULL; })
  67
  68/* Initialize an object to default values */
  69static inline void qobject_init(QObject *obj, QType type)
  70{
  71    assert(QTYPE_NONE < type && type < QTYPE__MAX);
  72    obj->refcnt = 1;
  73    obj->type = type;
  74}
  75
  76/**
  77 * qobject_incref(): Increment QObject's reference count
  78 */
  79static inline void qobject_incref(QObject *obj)
  80{
  81    if (obj)
  82        obj->refcnt++;
  83}
  84
  85/**
  86 * qobject_is_equal(): Return whether the two objects are equal.
  87 *
  88 * Any of the pointers may be NULL; return true if both are.  Always
  89 * return false if only one is (therefore a QNull object is not
  90 * considered equal to a NULL pointer).
  91 */
  92bool qobject_is_equal(const QObject *x, const QObject *y);
  93
  94/**
  95 * qobject_destroy(): Free resources used by the object
  96 */
  97void qobject_destroy(QObject *obj);
  98
  99/**
 100 * qobject_decref(): Decrement QObject's reference count, deallocate
 101 * when it reaches zero
 102 */
 103static inline void qobject_decref(QObject *obj)
 104{
 105    assert(!obj || obj->refcnt);
 106    if (obj && --obj->refcnt == 0) {
 107        qobject_destroy(obj);
 108    }
 109}
 110
 111/**
 112 * qobject_type(): Return the QObject's type
 113 */
 114static inline QType qobject_type(const QObject *obj)
 115{
 116    assert(QTYPE_NONE < obj->type && obj->type < QTYPE__MAX);
 117    return obj->type;
 118}
 119
 120/**
 121 * qobject_check_type(): Helper function for the qobject_to() macro.
 122 * Return @obj, but only if @obj is not NULL and @type is equal to
 123 * @obj's type.  Return NULL otherwise.
 124 */
 125static inline QObject *qobject_check_type(const QObject *obj, QType type)
 126{
 127    if (obj && qobject_type(obj) == type) {
 128        return (QObject *)obj;
 129    } else {
 130        return NULL;
 131    }
 132}
 133
 134#endif /* QOBJECT_H */
 135