mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
rust: types: extend Opaque
documentation
Update the `Opaque` documentation and add an example as proposed by Miguel Ojeda in [1]. The documentation update is mainly taken from Benno Lossin's description [2]. Cc: Nell Shamrell-Harrington <nells@linux.microsoft.com> Suggested-by: Miguel Ojeda <ojeda@kernel.org> Link: https://rust-for-linux.zulipchat.com/#narrow/stream/291565/topic/x/near/467478085 [1] Link: https://rust-for-linux.zulipchat.com/#narrow/stream/291565/topic/x/near/470498289 [2] Co-developed-by: Benno Lossin <benno.lossin@proton.me> Signed-off-by: Benno Lossin <benno.lossin@proton.me> Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com> Link: https://lore.kernel.org/r/20241002050301.1927545-1-dirk.behme@de.bosch.com [ Used `expect`. Rewrapped docs. Added intra-doc link. Formatted example. Reworded to fix tag typo/order. Fixed `&mut` formatting as discussed. Added Benno's SOB and CDB as discussed. Shortened links. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
28e848386b
commit
718c406989
@ -206,7 +206,58 @@ fn drop(&mut self) {
|
||||
|
||||
/// Stores an opaque value.
|
||||
///
|
||||
/// This is meant to be used with FFI objects that are never interpreted by Rust code.
|
||||
/// `Opaque<T>` is meant to be used with FFI objects that are never interpreted by Rust code.
|
||||
///
|
||||
/// It is used to wrap structs from the C side, like for example `Opaque<bindings::mutex>`.
|
||||
/// It gets rid of all the usual assumptions that Rust has for a value:
|
||||
///
|
||||
/// * The value is allowed to be uninitialized (for example have invalid bit patterns: `3` for a
|
||||
/// [`bool`]).
|
||||
/// * The value is allowed to be mutated, when a `&Opaque<T>` exists on the Rust side.
|
||||
/// * No uniqueness for mutable references: it is fine to have multiple `&mut Opaque<T>` point to
|
||||
/// the same value.
|
||||
/// * The value is not allowed to be shared with other threads (i.e. it is `!Sync`).
|
||||
///
|
||||
/// This has to be used for all values that the C side has access to, because it can't be ensured
|
||||
/// that the C side is adhering to the usual constraints that Rust needs.
|
||||
///
|
||||
/// Using `Opaque<T>` allows to continue to use references on the Rust side even for values shared
|
||||
/// with C.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![expect(unreachable_pub, clippy::disallowed_names)]
|
||||
/// use kernel::types::Opaque;
|
||||
/// # // Emulate a C struct binding which is from C, maybe uninitialized or not, only the C side
|
||||
/// # // knows.
|
||||
/// # mod bindings {
|
||||
/// # pub struct Foo {
|
||||
/// # pub val: u8,
|
||||
/// # }
|
||||
/// # }
|
||||
///
|
||||
/// // `foo.val` is assumed to be handled on the C side, so we use `Opaque` to wrap it.
|
||||
/// pub struct Foo {
|
||||
/// foo: Opaque<bindings::Foo>,
|
||||
/// }
|
||||
///
|
||||
/// impl Foo {
|
||||
/// pub fn get_val(&self) -> u8 {
|
||||
/// let ptr = Opaque::get(&self.foo);
|
||||
///
|
||||
/// // SAFETY: `Self` is valid from C side.
|
||||
/// unsafe { (*ptr).val }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // Create an instance of `Foo` with the `Opaque` wrapper.
|
||||
/// let foo = Foo {
|
||||
/// foo: Opaque::new(bindings::Foo { val: 0xdb }),
|
||||
/// };
|
||||
///
|
||||
/// assert_eq!(foo.get_val(), 0xdb);
|
||||
/// ```
|
||||
#[repr(transparent)]
|
||||
pub struct Opaque<T> {
|
||||
value: UnsafeCell<MaybeUninit<T>>,
|
||||
|
Loading…
Reference in New Issue
Block a user