summary refs log tree commit diff stats
path: root/include/qobject/qobject.h
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2024-11-18 16:12:34 +0100
committerMarkus Armbruster <armbru@redhat.com>2025-02-10 15:33:16 +0100
commit407bc4bf9027f7ac4333e47cd900d773b99a23e3 (patch)
tree6f617801cce2d4715d586e15a2523488bdd68711 /include/qobject/qobject.h
parent04d3d0e9f54d4c42759f3810aa135ce314d98dc4 (diff)
downloadfocaccia-qemu-407bc4bf9027f7ac4333e47cd900d773b99a23e3.tar.gz
focaccia-qemu-407bc4bf9027f7ac4333e47cd900d773b99a23e3.zip
qapi: Move include/qapi/qmp/ to include/qobject/
The general expectation is that header files should follow the same
file/path naming scheme as the corresponding source file. There are
various historical exceptions to this practice in QEMU, with one of
the most notable being the include/qapi/qmp/ directory. Most of the
headers there correspond to source files in qobject/.

This patch corrects most of that inconsistency by creating
include/qobject/ and moving the headers for qobject/ there.

This also fixes MAINTAINERS for include/qapi/qmp/dispatch.h:
scripts/get_maintainer.pl now reports "QAPI" instead of "No
maintainers found".

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Acked-by: Halil Pasic <pasic@linux.ibm.com> #s390x
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20241118151235.2665921-2-armbru@redhat.com>
[Rebased]
Diffstat (limited to 'include/qobject/qobject.h')
-rw-r--r--include/qobject/qobject.h144
1 files changed, 144 insertions, 0 deletions
diff --git a/include/qobject/qobject.h b/include/qobject/qobject.h
new file mode 100644
index 0000000000..a6244d0ce0
--- /dev/null
+++ b/include/qobject/qobject.h
@@ -0,0 +1,144 @@
+/*
+ * QEMU Object Model.
+ *
+ * Based on ideas by Avi Kivity <avi@redhat.com>
+ *
+ * Copyright (C) 2009, 2015 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ * QObject Reference Counts Terminology
+ * ------------------------------------
+ *
+ *  - Returning references: A function that returns an object may
+ *  return it as either a weak or a strong reference.  If the
+ *  reference is strong, you are responsible for calling
+ *  qobject_unref() on the reference when you are done.
+ *
+ *  If the reference is weak, the owner of the reference may free it at
+ *  any time in the future.  Before storing the reference anywhere, you
+ *  should call qobject_ref() to make the reference strong.
+ *
+ *  - Transferring ownership: when you transfer ownership of a reference
+ *  by calling a function, you are no longer responsible for calling
+ *  qobject_unref() when the reference is no longer needed.  In other words,
+ *  when the function returns you must behave as if the reference to the
+ *  passed object was weak.
+ */
+#ifndef QOBJECT_H
+#define QOBJECT_H
+
+#include "qapi/qapi-builtin-types.h"
+
+/* Not for use outside include/qobject/ */
+struct QObjectBase_ {
+    QType type;
+    size_t refcnt;
+};
+
+/* this struct must have no other members than base */
+struct QObject {
+    struct QObjectBase_ base;
+};
+
+/*
+ * Preprocessor sorcery ahead: use a different identifier for the
+ * local variable in each expansion, so we can nest macro calls
+ * without shadowing variables.
+ */
+#define QOBJECT_INTERNAL(obj, _obj) ({                          \
+    typeof(obj) _obj = (obj);                                   \
+    _obj ? container_of(&_obj->base, QObject, base) : NULL;     \
+})
+#define QOBJECT(obj) QOBJECT_INTERNAL((obj), MAKE_IDENTIFIER(_obj))
+
+/* Required for qobject_to() */
+#define QTYPE_CAST_TO_QNull     QTYPE_QNULL
+#define QTYPE_CAST_TO_QNum      QTYPE_QNUM
+#define QTYPE_CAST_TO_QString   QTYPE_QSTRING
+#define QTYPE_CAST_TO_QDict     QTYPE_QDICT
+#define QTYPE_CAST_TO_QList     QTYPE_QLIST
+#define QTYPE_CAST_TO_QBool     QTYPE_QBOOL
+
+QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7,
+                   "The QTYPE_CAST_TO_* list needs to be extended");
+
+#define qobject_to(type, obj)                                       \
+    ((type *)qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)))
+
+static inline void qobject_ref_impl(QObject *obj)
+{
+    if (obj) {
+        obj->base.refcnt++;
+    }
+}
+
+/**
+ * qobject_is_equal(): Return whether the two objects are equal.
+ *
+ * Any of the pointers may be NULL; return true if both are.  Always
+ * return false if only one is (therefore a QNull object is not
+ * considered equal to a NULL pointer).
+ */
+bool qobject_is_equal(const QObject *x, const QObject *y);
+
+/**
+ * qobject_destroy(): Free resources used by the object
+ * For use via qobject_unref() only!
+ */
+void qobject_destroy(QObject *obj);
+
+static inline void qobject_unref_impl(QObject *obj)
+{
+    assert(!obj || obj->base.refcnt);
+    if (obj && --obj->base.refcnt == 0) {
+        qobject_destroy(obj);
+    }
+}
+
+/**
+ * qobject_ref(): Increment QObject's reference count
+ *
+ * Returns: the same @obj. The type of @obj will be propagated to the
+ * return type.
+ */
+#define qobject_ref(obj) ({                     \
+    typeof(obj) _o = (obj);                     \
+    qobject_ref_impl(QOBJECT(_o));              \
+    _o;                                         \
+})
+
+/**
+ * qobject_unref(): Decrement QObject's reference count, deallocate
+ * when it reaches zero
+ */
+#define qobject_unref(obj) qobject_unref_impl(QOBJECT(obj))
+
+/**
+ * qobject_type(): Return the QObject's type
+ */
+static inline QType qobject_type(const QObject *obj)
+{
+    assert(QTYPE_NONE < obj->base.type && obj->base.type < QTYPE__MAX);
+    return obj->base.type;
+}
+
+/**
+ * qobject_check_type(): Helper function for the qobject_to() macro.
+ * Return @obj, but only if @obj is not NULL and @type is equal to
+ * @obj's type.  Return NULL otherwise.
+ */
+static inline QObject *qobject_check_type(const QObject *obj, QType type)
+{
+    if (obj && qobject_type(obj) == type) {
+        return (QObject *)obj;
+    } else {
+        return NULL;
+    }
+}
+
+#endif /* QOBJECT_H */