Home
last modified time | relevance | path

Searched hist:ca0d60a6ad777ab617cbc4e6f328eaff60617b3f (Results 1 – 3 of 3) sorted by relevance

/qemu/rust/qemu-api/src/
H A Dqom.rsca0d60a6ad777ab617cbc4e6f328eaff60617b3f Wed Dec 11 10:38:20 UTC 2024 Paolo Bonzini <pbonzini@redhat.com> rust: qom: add ParentField

Add a type that, together with the C function object_deinit, ensures the
correct drop order for QOM objects relative to their superclasses.

Right now it is not possible to implement the Drop trait for QOM classes
that are defined in Rust, as the drop() function would not be called when
the object goes away; instead what is called is ObjectImpl::INSTANCE_FINALIZE.
It would be nice for INSTANCE_FINALIZE to just drop the object, but this has
a problem: suppose you have

pub struct MySuperclass {
parent: DeviceState,
field: Box<MyData>,
...
}

impl Drop for MySuperclass {
...
}

pub struct MySubclass {
parent: MySuperclass,
...
}

and an instance_finalize implementation that is like

unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut Object) {
unsafe { std::ptr::drop_in_place(obj.cast::<T>()) }
}

When instance_finalize is called for MySubclass, it will walk the struct's
list of fields and call the drop method for MySuperclass. Then, object_deinit
recurses to the superclass and calls the same drop method again. This
will cause double-freeing of the Box<Data>.

What's happening here is that QOM wants to control the drop order of
MySuperclass and MySubclass's fields. To do so, the parent field must
be marked ManuallyDrop<>, which is quite ugly. Instead, add a wrapper
type ParentField<> that is specific to QOM. This hides the implementation
detail of *what* is special about the ParentField, and will also be easy
to check in the #[derive(Object)] macro.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
/qemu/rust/qemu-api/tests/
H A Dtests.rsca0d60a6ad777ab617cbc4e6f328eaff60617b3f Wed Dec 11 10:38:20 UTC 2024 Paolo Bonzini <pbonzini@redhat.com> rust: qom: add ParentField

Add a type that, together with the C function object_deinit, ensures the
correct drop order for QOM objects relative to their superclasses.

Right now it is not possible to implement the Drop trait for QOM classes
that are defined in Rust, as the drop() function would not be called when
the object goes away; instead what is called is ObjectImpl::INSTANCE_FINALIZE.
It would be nice for INSTANCE_FINALIZE to just drop the object, but this has
a problem: suppose you have

pub struct MySuperclass {
parent: DeviceState,
field: Box<MyData>,
...
}

impl Drop for MySuperclass {
...
}

pub struct MySubclass {
parent: MySuperclass,
...
}

and an instance_finalize implementation that is like

unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut Object) {
unsafe { std::ptr::drop_in_place(obj.cast::<T>()) }
}

When instance_finalize is called for MySubclass, it will walk the struct's
list of fields and call the drop method for MySuperclass. Then, object_deinit
recurses to the superclass and calls the same drop method again. This
will cause double-freeing of the Box<Data>.

What's happening here is that QOM wants to control the drop order of
MySuperclass and MySubclass's fields. To do so, the parent field must
be marked ManuallyDrop<>, which is quite ugly. Instead, add a wrapper
type ParentField<> that is specific to QOM. This hides the implementation
detail of *what* is special about the ParentField, and will also be easy
to check in the #[derive(Object)] macro.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
/qemu/rust/hw/char/pl011/src/
H A Ddevice.rsca0d60a6ad777ab617cbc4e6f328eaff60617b3f Wed Dec 11 10:38:20 UTC 2024 Paolo Bonzini <pbonzini@redhat.com> rust: qom: add ParentField

Add a type that, together with the C function object_deinit, ensures the
correct drop order for QOM objects relative to their superclasses.

Right now it is not possible to implement the Drop trait for QOM classes
that are defined in Rust, as the drop() function would not be called when
the object goes away; instead what is called is ObjectImpl::INSTANCE_FINALIZE.
It would be nice for INSTANCE_FINALIZE to just drop the object, but this has
a problem: suppose you have

pub struct MySuperclass {
parent: DeviceState,
field: Box<MyData>,
...
}

impl Drop for MySuperclass {
...
}

pub struct MySubclass {
parent: MySuperclass,
...
}

and an instance_finalize implementation that is like

unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut Object) {
unsafe { std::ptr::drop_in_place(obj.cast::<T>()) }
}

When instance_finalize is called for MySubclass, it will walk the struct's
list of fields and call the drop method for MySuperclass. Then, object_deinit
recurses to the superclass and calls the same drop method again. This
will cause double-freeing of the Box<Data>.

What's happening here is that QOM wants to control the drop order of
MySuperclass and MySubclass's fields. To do so, the parent field must
be marked ManuallyDrop<>, which is quite ugly. Instead, add a wrapper
type ParentField<> that is specific to QOM. This hides the implementation
detail of *what* is special about the ParentField, and will also be easy
to check in the #[derive(Object)] macro.

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