On Wed, Oct 8, 2025 at 6:16 PM Daniel P. Berrangé <[email protected]> wrote:
> > C code will
> > have to agree with not making changes to the QObjects after they've
> > been passed to Rust code.
>
> I wonder whether that latter constraint on the C code will hold
> true in practice ? Particularly thinking about scenarios where
> we add/remove link properties to QObject's, potentially at any
> time during life of QEMU via QMP/HMP commands ?
Those are QOM objects, not QObjects (the QMP/JSON data model) which
are what this patch affects.
C "things" that are not thread-safe are protected by
"assert!(bql::is_locked!())", either written explicitly or hidden
behind BqlCell/BqlRefCell.
In this case, the safety is covered by QObject::from_raw being unsafe.
Whoever calls it needs to know that the C code is not going to mutate
the QObject until the Rust side is done with it.
> With this unref method being void, how does the Rust code
> know when a QObject is no longer alive after it has called
> unref ? Does it need to know this to provide any safety
> guarantees ?
No, the safety guarantees can come from knowledge of what the C code will do.
In particular, the safety is covered by QObject::from_raw being
unsafe. Whoever calls it needs to know that the C code is not going to
mutate the QObject until the Rust side is done with it. This for
example is true of arguments to QMP commands, which are the main case
where C could pass QObjects directly to Rust.
Something like
void qmp_marshal_query_stats(QDict *args, QObject **ret, Error **errp)
would become
fn qmp_marshal_query_stats(args: *mut QDict,
retp: *mut *mut QObject, errp: *mut *mut Error)
{
let qobj = unsafe { QObject::cloned_from_raw(args.cast()) };
let result = from_qobject::<StatsFilter>(qobj)
.map_err(Into::into)
.and_then(qmp_query_stats);
match result {
Ok(ret) => {
let ret_qobj = to_qobject::<Vec<StatsResult>>(ret);
unsafe { *retp = ret_qobj.into_raw(); }
},
Err(e) => unsafe { e.propagate(errp) },
}
}
(and even discounting the lack of tracing, that's quite a bit smaller
than the C code thanks to all the automatic consumption of args and
ret when passed respectively to qmp_query_stats and to_qobject, just
by virtue of how those functions are declared).
Paolo