Skip to content

Commit

Permalink
Implement FromGlibPtrBorrow on boxed and shared-boxed types
Browse files Browse the repository at this point in the history
  • Loading branch information
Matteo Biggio committed Jul 6, 2023
1 parent d8bf481 commit 7d2fb90
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
19 changes: 19 additions & 0 deletions glib-macros/src/boxed_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,25 @@ pub fn impl_boxed(input: &syn::DeriveInput) -> TokenStream {

#impl_from_value

impl #crate_ident::translate::FromGlibPtrBorrow<*const #name> for #name {
#[inline]
unsafe fn from_glib_borrow(ptr: *const #name) -> #crate_ident::translate::Borrowed<Self> {
#crate_ident::translate::FromGlibPtrBorrow::from_glib_borrow(ptr as *mut _)
}
}

impl #crate_ident::translate::FromGlibPtrBorrow<*mut #name> for #name {
#[inline]
unsafe fn from_glib_borrow(ptr: *mut #name) -> #crate_ident::translate::Borrowed<Self> {
debug_assert!(!ptr.is_null());

// from_raw is taking ownership of the raw pointer here, but wrapping its result
// in Borrowed::new ensures that it won't be deallocated when it will go out of
// scope, so the pointer will still be valid afterwards
#crate_ident::translate::Borrowed::new(*::std::boxed::Box::from_raw(ptr))
}
}

impl #crate_ident::translate::FromGlibPtrNone<*const #name> for #name {
#[inline]
unsafe fn from_glib_none(ptr: *const #name) -> Self {
Expand Down
20 changes: 20 additions & 0 deletions glib-macros/src/shared_boxed_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,26 @@ pub fn impl_shared_boxed(input: &syn::DeriveInput) -> proc_macro2::TokenStream {

#impl_from_value

impl #crate_ident::translate::FromGlibPtrBorrow<*const #refcounted_type_prefix::InnerType> for #name {
#[inline]
unsafe fn from_glib_borrow(ptr: *const #refcounted_type_prefix::InnerType) -> #crate_ident::translate::Borrowed<Self> {
debug_assert!(!ptr.is_null());

// from_raw is taking ownership of the raw pointer here, but wrapping its result
// in Borrowed::new ensures that it won't be deallocated when it will go out of
// scope, so the pointer will still be valid afterwards
#crate_ident::translate::Borrowed::new(#name(#refcounted_type_prefix::from_raw(ptr)))
}
}

impl #crate_ident::translate::FromGlibPtrBorrow<*mut #refcounted_type_prefix::InnerType> for #name {
#[inline]
unsafe fn from_glib_borrow(ptr: *mut #refcounted_type_prefix::InnerType) -> #crate_ident::translate::Borrowed<Self> {
#crate_ident::translate::FromGlibPtrBorrow::from_glib_borrow(ptr as *const _)
}
}


impl #crate_ident::translate::FromGlibPtrNone<*const #refcounted_type_prefix::InnerType> for #name {
#[inline]
unsafe fn from_glib_none(ptr: *const #refcounted_type_prefix::InnerType) -> Self {
Expand Down
40 changes: 40 additions & 0 deletions glib/src/subclass/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,44 @@ mod test {
unsafe { <MySharedRc as SharedType>::RefCountedType::from_raw(inner_raw_ptr_clone) };
assert_eq!(std::rc::Rc::strong_count(&b.0), 1);
}

#[test]
fn from_glib_borrow_arc() {
assert_ne!(crate::Type::INVALID, MySharedRc::static_type());

let b = MySharedArc::from_refcounted(std::sync::Arc::new(MySharedInner {
foo: String::from("abc"),
}));

let inner_raw_ptr = std::sync::Arc::into_raw(b.clone().0);

assert_eq!(std::sync::Arc::strong_count(&b.0), 2);

unsafe {
let _ = MySharedArc::from_glib_borrow(inner_raw_ptr);
assert_eq!(std::sync::Arc::strong_count(&b.0), 2);
}

assert_eq!(std::sync::Arc::strong_count(&b.0), 2);
}

#[test]
fn from_glib_borrow_rc() {
assert_ne!(crate::Type::INVALID, MySharedRc::static_type());

let b = MySharedRc::from_refcounted(std::rc::Rc::new(MySharedInner {
foo: String::from("abc"),
}));

let inner_raw_ptr = std::rc::Rc::into_raw(b.clone().0);

assert_eq!(std::rc::Rc::strong_count(&b.0), 2);

unsafe {
let _ = MySharedRc::from_glib_borrow(inner_raw_ptr);
assert_eq!(std::rc::Rc::strong_count(&b.0), 2);
}

assert_eq!(std::rc::Rc::strong_count(&b.0), 2);
}
}

0 comments on commit 7d2fb90

Please sign in to comment.