All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: Wedson Almeida Filho <wedsonaf@gmail.com>
Cc: rust-for-linux@vger.kernel.org, "Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/5] rust: types: introduce `ForeignOwnable`
Date: Fri, 20 Jan 2023 11:59:29 -0800	[thread overview]
Message-ID: <Y8ryoTYIKpYtuqow@boqun-archlinux> (raw)
In-Reply-To: <20230119174036.64046-2-wedsonaf@gmail.com>

On Thu, Jan 19, 2023 at 02:40:33PM -0300, Wedson Almeida Filho wrote:
> It was originally called `PointerWrapper`. It is used to convert
> a Rust object to a pointer representation (void *) that can be
> stored on the C side, used, and eventually returned to Rust.
> 
> Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
> ---
>  rust/kernel/lib.rs   |  1 +
>  rust/kernel/types.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 55 insertions(+)
> 
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index e0b0e953907d..223564f9f0cc 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -16,6 +16,7 @@
>  #![feature(coerce_unsized)]
>  #![feature(core_ffi_c)]
>  #![feature(dispatch_from_dyn)]
> +#![feature(generic_associated_types)]
>  #![feature(receiver_trait)]
>  #![feature(unsize)]
>  
> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> index f0ad4472292d..5475f6163002 100644
> --- a/rust/kernel/types.rs
> +++ b/rust/kernel/types.rs
> @@ -9,6 +9,60 @@ use core::{
>      ops::{Deref, DerefMut},
>  };
>  
> +/// Used to transfer ownership to and from foreign (non-Rust) languages.
> +///
> +/// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
> +/// later may be transferred back to Rust by calling [`Self::from_foreign`].
> +///
> +/// This trait is meant to be used in cases when Rust objects are stored in C objects and
> +/// eventually "freed" back to Rust.
> +pub trait ForeignOwnable {
> +    /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and
> +    /// [`ForeignOwnable::from_foreign`].
> +    type Borrowed<'a>;
> +
> +    /// Converts a Rust-owned object to a foreign-owned one.
> +    ///
> +    /// The foreign representation is a pointer to void.
> +    fn into_foreign(self) -> *const core::ffi::c_void;
> +
> +    /// Borrows a foreign-owned object.
> +    ///
> +    /// # Safety
> +    ///
> +    /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
> +    /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
> +    /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow_mut`]
> +    /// for this object must have been dropped.
> +    unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<'a>;
> +
> +    /// Mutably borrows a foreign-owned object.
> +    ///
> +    /// # Safety
> +    ///
> +    /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
> +    /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
> +    /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and
> +    /// [`ForeignOwnable::borrow_mut`] for this object must have been dropped.
> +    unsafe fn borrow_mut<T: ForeignOwnable>(ptr: *const core::ffi::c_void) -> ScopeGuard<T, fn(T)> {
> +        // SAFETY: The safety requirements ensure that `ptr` came from a previous call to
> +        // `into_foreign`.
> +        ScopeGuard::new_with_data(unsafe { T::from_foreign(ptr) }, |d| {
> +            d.into_foreign();
> +        })

I kinda want to suggest borrow_mut() to be implemented as:

    pub trait ForeignOwnable {
        ...
        unsafe fn borrow_mut(ptr: *const core::ffi::c_void) -> ScopeGuard<Self, fn(Self)> {
            // SAFETY: The safety requirements ensure that `ptr` came from a previous call to
            // `into_foreign`.
            ScopeGuard::new_with_data(unsafe { Self::from_foreign(ptr) }, |d| {
                d.into_foreign();
            })
    }

to avoid funny code as follow:

	let a = Box::new(0).into_foreign();
	// Using an irrelevant `impl ForeignOwnable` to `borrow_mut`
	let borrowed_a: ScopeGuard<Box<i32>, ...> = unsafe { Arc::<u64>::borrow_mut(a) };

but that requires `Self: Sized`. Is it too restrictive?

Regards,
Boqun

> +    }
> +
> +    /// Converts a foreign-owned object back to a Rust-owned one.
> +    ///
> +    /// # Safety
> +    ///
> +    /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
> +    /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
> +    /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and
> +    /// [`ForeignOwnable::borrow_mut`] for this object must have been dropped.
> +    unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self;
> +}
> +
>  /// Runs a cleanup function/closure when dropped.
>  ///
>  /// The [`ScopeGuard::dismiss`] function prevents the cleanup function from running.
> -- 
> 2.34.1
> 

  reply	other threads:[~2023-01-20 20:00 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-19 17:40 [PATCH 1/5] rust: types: introduce `ScopeGuard` Wedson Almeida Filho
2023-01-19 17:40 ` [PATCH 2/5] rust: types: introduce `ForeignOwnable` Wedson Almeida Filho
2023-01-20 19:59   ` Boqun Feng [this message]
2023-01-22  6:34     ` Wedson Almeida Filho
2023-01-27 13:55   ` Gary Guo
2023-01-30  5:59     ` Wedson Almeida Filho
2023-01-28 10:42   ` Vincenzo Palazzo
2023-01-28 14:53   ` Martin Rodriguez Reboredo
2023-01-28 17:05     ` Boqun Feng
2023-01-28 20:46       ` Martin Rodriguez Reboredo
2023-01-28 22:07         ` Boqun Feng
2023-01-29  3:52           ` Martin Rodriguez Reboredo
2023-01-19 17:40 ` [PATCH 3/5] rust: types: implement `ForeignOwnable` for `Box<T>` Wedson Almeida Filho
2023-01-27 13:56   ` Gary Guo
2023-01-28 10:50   ` Vincenzo Palazzo
2023-01-30  5:33   ` Alice Ferrazzi
2023-01-19 17:40 ` [PATCH 4/5] rust: types: implement `ForeignOwnable` for the unit type Wedson Almeida Filho
2023-01-27 14:03   ` Gary Guo
2023-01-27 14:11     ` Miguel Ojeda
2023-01-28 11:13       ` Vincenzo Palazzo
2023-01-30 17:21         ` Miguel Ojeda
2023-01-30  5:55     ` Wedson Almeida Filho
2023-01-28 11:14   ` Vincenzo Palazzo
2023-01-19 17:40 ` [PATCH 5/5] rust: types: implement `ForeignOwnable` for `Arc<T>` Wedson Almeida Filho
2023-01-27 14:04   ` Gary Guo
2023-01-28 11:15   ` Vincenzo Palazzo
2023-01-30  5:35   ` Alice Ferrazzi
2023-01-20  6:23 ` [PATCH 1/5] rust: types: introduce `ScopeGuard` Boqun Feng
2023-01-22  6:31   ` Wedson Almeida Filho
2023-01-28 10:38 ` Vincenzo Palazzo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y8ryoTYIKpYtuqow@boqun-archlinux \
    --to=boqun.feng@gmail.com \
    --cc=alex.gaynor@gmail.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=gary@garyguo.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=wedsonaf@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.