]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
qobject: make refcount atomic
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 30 Sep 2025 11:17:11 +0000 (13:17 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 28 Oct 2025 12:02:26 +0000 (13:02 +0100)
The Rust bindings for QObject will only operate on complete objects,
treating them as immutable as long as the Rust QObject is live.

With that constraint, it is trivial for Rust code to treat QObjects as
thread-safe; all that's needed is to make reference count operations
atomic.  Do the same when the C code adds or removes references, since
we don't really know what the Rust code is up to; of course C code will
have to agree with not making changes to the QObjects after they've
been passed to Rust code.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
include/qobject/qobject.h

index a6244d0ce000a7beeedd4594a2febd351efbb1ab..02f4c6a6eb2f2400a0f123b188cf8bbfca0a3609 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef QOBJECT_H
 #define QOBJECT_H
 
+#include "qemu/atomic.h"
 #include "qapi/qapi-builtin-types.h"
 
 /* Not for use outside include/qobject/ */
@@ -73,7 +74,7 @@ QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7,
 static inline void qobject_ref_impl(QObject *obj)
 {
     if (obj) {
-        obj->base.refcnt++;
+        qatomic_inc(&obj->base.refcnt);
     }
 }
 
@@ -95,7 +96,7 @@ void qobject_destroy(QObject *obj);
 static inline void qobject_unref_impl(QObject *obj)
 {
     assert(!obj || obj->base.refcnt);
-    if (obj && --obj->base.refcnt == 0) {
+    if (obj && qatomic_fetch_dec(&obj->base.refcnt) == 1) {
         qobject_destroy(obj);
     }
 }