mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-27 04:13:53 -06:00
rust: qom: wrap Object with Opaque<>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9c9a6a889c
commit
7fb4a99df1
4 changed files with 26 additions and 20 deletions
|
@ -46,9 +46,6 @@ unsafe impl Sync for MemoryRegion {}
|
|||
unsafe impl Send for ObjectClass {}
|
||||
unsafe impl Sync for ObjectClass {}
|
||||
|
||||
unsafe impl Send for Object {}
|
||||
unsafe impl Sync for Object {}
|
||||
|
||||
unsafe impl Send for SysBusDevice {}
|
||||
unsafe impl Sync for SysBusDevice {}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ impl MemoryRegion {
|
|||
let cstr = CString::new(name).unwrap();
|
||||
memory_region_init_io(
|
||||
slot,
|
||||
owner.cast::<Object>(),
|
||||
owner.cast::<bindings::Object>(),
|
||||
ops,
|
||||
owner.cast::<c_void>(),
|
||||
cstr.as_ptr(),
|
||||
|
|
|
@ -52,7 +52,7 @@ pub trait ResettablePhasesImpl {
|
|||
/// can be downcasted to type `T`. We also expect the device is
|
||||
/// readable/writeable from one thread at any time.
|
||||
unsafe extern "C" fn rust_resettable_enter_fn<T: ResettablePhasesImpl>(
|
||||
obj: *mut Object,
|
||||
obj: *mut bindings::Object,
|
||||
typ: ResetType,
|
||||
) {
|
||||
let state = NonNull::new(obj).unwrap().cast::<T>();
|
||||
|
@ -65,7 +65,7 @@ unsafe extern "C" fn rust_resettable_enter_fn<T: ResettablePhasesImpl>(
|
|||
/// can be downcasted to type `T`. We also expect the device is
|
||||
/// readable/writeable from one thread at any time.
|
||||
unsafe extern "C" fn rust_resettable_hold_fn<T: ResettablePhasesImpl>(
|
||||
obj: *mut Object,
|
||||
obj: *mut bindings::Object,
|
||||
typ: ResetType,
|
||||
) {
|
||||
let state = NonNull::new(obj).unwrap().cast::<T>();
|
||||
|
@ -78,7 +78,7 @@ unsafe extern "C" fn rust_resettable_hold_fn<T: ResettablePhasesImpl>(
|
|||
/// can be downcasted to type `T`. We also expect the device is
|
||||
/// readable/writeable from one thread at any time.
|
||||
unsafe extern "C" fn rust_resettable_exit_fn<T: ResettablePhasesImpl>(
|
||||
obj: *mut Object,
|
||||
obj: *mut bindings::Object,
|
||||
typ: ResetType,
|
||||
) {
|
||||
let state = NonNull::new(obj).unwrap().cast::<T>();
|
||||
|
|
|
@ -101,16 +101,24 @@ use std::{
|
|||
ptr::NonNull,
|
||||
};
|
||||
|
||||
pub use bindings::{Object, ObjectClass};
|
||||
pub use bindings::ObjectClass;
|
||||
|
||||
use crate::{
|
||||
bindings::{
|
||||
self, object_class_dynamic_cast, object_dynamic_cast, object_get_class,
|
||||
object_get_typename, object_new, object_ref, object_unref, TypeInfo,
|
||||
},
|
||||
cell::bql_locked,
|
||||
cell::{bql_locked, Opaque},
|
||||
};
|
||||
|
||||
/// A safe wrapper around [`bindings::Object`].
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, qemu_api_macros::Wrapper)]
|
||||
pub struct Object(Opaque<bindings::Object>);
|
||||
|
||||
unsafe impl Send for Object {}
|
||||
unsafe impl Sync for Object {}
|
||||
|
||||
/// Marker trait: `Self` can be statically upcasted to `P` (i.e. `P` is a direct
|
||||
/// or indirect parent of `Self`).
|
||||
///
|
||||
|
@ -199,7 +207,7 @@ impl<T: fmt::Display + ObjectType> fmt::Display for ParentField<T> {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn rust_instance_init<T: ObjectImpl>(obj: *mut Object) {
|
||||
unsafe extern "C" fn rust_instance_init<T: ObjectImpl>(obj: *mut bindings::Object) {
|
||||
let mut state = NonNull::new(obj).unwrap().cast::<T>();
|
||||
// SAFETY: obj is an instance of T, since rust_instance_init<T>
|
||||
// is called from QOM core as the instance_init function
|
||||
|
@ -209,7 +217,7 @@ unsafe extern "C" fn rust_instance_init<T: ObjectImpl>(obj: *mut Object) {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn rust_instance_post_init<T: ObjectImpl>(obj: *mut Object) {
|
||||
unsafe extern "C" fn rust_instance_post_init<T: ObjectImpl>(obj: *mut bindings::Object) {
|
||||
let state = NonNull::new(obj).unwrap().cast::<T>();
|
||||
// SAFETY: obj is an instance of T, since rust_instance_post_init<T>
|
||||
// is called from QOM core as the instance_post_init function
|
||||
|
@ -230,7 +238,7 @@ unsafe extern "C" fn rust_class_init<T: ObjectType + ObjectImpl>(
|
|||
<T as ObjectImpl>::CLASS_INIT(unsafe { klass.as_mut() })
|
||||
}
|
||||
|
||||
unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut Object) {
|
||||
unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut bindings::Object) {
|
||||
// SAFETY: obj is an instance of T, since drop_object<T> is called
|
||||
// from the QOM core function object_deinit() as the instance_finalize
|
||||
// function for class T. Note that while object_deinit() will drop the
|
||||
|
@ -280,14 +288,14 @@ pub unsafe trait ObjectType: Sized {
|
|||
/// Return the receiver as an Object. This is always safe, even
|
||||
/// if this type represents an interface.
|
||||
fn as_object(&self) -> &Object {
|
||||
unsafe { &*self.as_object_ptr() }
|
||||
unsafe { &*self.as_ptr().cast() }
|
||||
}
|
||||
|
||||
/// Return the receiver as a const raw pointer to Object.
|
||||
/// This is preferrable to `as_object_mut_ptr()` if a C
|
||||
/// function only needs a `const Object *`.
|
||||
fn as_object_ptr(&self) -> *const Object {
|
||||
self.as_ptr().cast()
|
||||
fn as_object_ptr(&self) -> *const bindings::Object {
|
||||
self.as_object().as_ptr()
|
||||
}
|
||||
|
||||
/// Return the receiver as a mutable raw pointer to Object.
|
||||
|
@ -297,8 +305,8 @@ pub unsafe trait ObjectType: Sized {
|
|||
/// This cast is always safe, but because the result is mutable
|
||||
/// and the incoming reference is not, this should only be used
|
||||
/// for calls to C functions, and only if needed.
|
||||
unsafe fn as_object_mut_ptr(&self) -> *mut Object {
|
||||
self.as_object_ptr() as *mut _
|
||||
unsafe fn as_object_mut_ptr(&self) -> *mut bindings::Object {
|
||||
self.as_object().as_mut_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,7 +629,7 @@ pub trait ObjectImpl: ObjectType + IsA<Object> {
|
|||
/// We expect the FFI user of this function to pass a valid pointer that
|
||||
/// can be downcasted to type `T`. We also expect the device is
|
||||
/// readable/writeable from one thread at any time.
|
||||
unsafe extern "C" fn rust_unparent_fn<T: ObjectImpl>(dev: *mut Object) {
|
||||
unsafe extern "C" fn rust_unparent_fn<T: ObjectImpl>(dev: *mut bindings::Object) {
|
||||
let state = NonNull::new(dev).unwrap().cast::<T>();
|
||||
T::UNPARENT.unwrap()(unsafe { state.as_ref() });
|
||||
}
|
||||
|
@ -796,8 +804,9 @@ pub trait ObjectClassMethods: IsA<Object> {
|
|||
// SAFETY: the object created by object_new is allocated on
|
||||
// the heap and has a reference count of 1
|
||||
unsafe {
|
||||
let obj = &*object_new(Self::TYPE_NAME.as_ptr());
|
||||
Owned::from_raw(obj.unsafe_cast::<Self>())
|
||||
let raw_obj = object_new(Self::TYPE_NAME.as_ptr());
|
||||
let obj = Object::from_raw(raw_obj).unsafe_cast::<Self>();
|
||||
Owned::from_raw(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue