diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2025-02-14 12:09:53 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2025-03-06 12:44:46 +0100 |
commit | 7fb4a99df17c8ae5f5e00d643042b9d95477a426 (patch) | |
tree | 8ac391aa8fb526cfa2fe4984301c47022862c31c /rust/qemu-api | |
parent | 9c9a6a889cb3589779b019a343892aa0e9bdb254 (diff) | |
download | qemu-7fb4a99df17c8ae5f5e00d643042b9d95477a426.zip qemu-7fb4a99df17c8ae5f5e00d643042b9d95477a426.tar.gz qemu-7fb4a99df17c8ae5f5e00d643042b9d95477a426.tar.bz2 |
rust: qom: wrap Object with Opaque<>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'rust/qemu-api')
-rw-r--r-- | rust/qemu-api/src/bindings.rs | 3 | ||||
-rw-r--r-- | rust/qemu-api/src/memory.rs | 2 | ||||
-rw-r--r-- | rust/qemu-api/src/qdev.rs | 6 | ||||
-rw-r--r-- | rust/qemu-api/src/qom.rs | 35 |
4 files changed, 26 insertions, 20 deletions
diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index d286863..be6dd68 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -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 {} diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs index 682951a..713c494 100644 --- a/rust/qemu-api/src/memory.rs +++ b/rust/qemu-api/src/memory.rs @@ -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(), diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index c136457..1a4d1f3 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -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>(); diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 5488643..2defbd2 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -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) } } } |