<[email protected]> writes:

> On Mon, Feb 23, 2026 at 03:59:22PM +0100, Andreas Hindborg wrote:
>> Alice Ryhl <[email protected]> writes:
>>
>> > On Fri, Feb 20, 2026 at 10:51:10AM +0100, Andreas Hindborg wrote:
>> >> From: Asahi Lina <[email protected]>
>> >>
>> >> By analogy to `AlwaysRefCounted` and `ARef`, an `Ownable` type is a
>> >> (typically C FFI) type that *may* be owned by Rust, but need not be. 
>> >> Unlike
>> >> `AlwaysRefCounted`, this mechanism expects the reference to be unique
>> >> within Rust, and does not allow cloning.
>> >>
>> >> Conceptually, this is similar to a `KBox<T>`, except that it delegates
>> >> resource management to the `T` instead of using a generic allocator.
>> >>
>> >> [ om:
>> >>   - Split code into separate file and `pub use` it from types.rs.
>> >>   - Make from_raw() and into_raw() public.
>> >>   - Remove OwnableMut, and make DerefMut dependent on Unpin instead.
>> >>   - Usage example/doctest for Ownable/Owned.
>> >>   - Fixes to documentation and commit message.
>> >> ]
>> >>
>> >> Link: 
>> >> https://lore.kernel.org/all/[email protected]/
>> >> Signed-off-by: Asahi Lina <[email protected]>
>> >> Co-developed-by: Oliver Mangold <[email protected]>
>> >> Signed-off-by: Oliver Mangold <[email protected]>
>> >> Reviewed-by: Boqun Feng <[email protected]>
>> >> Reviewed-by: Daniel Almeida <[email protected]>
>> >> [ Andreas: Updated documentation, examples, and formatting ]
>> >> Reviewed-by: Gary Guo <[email protected]>
>> >> Co-developed-by: Andreas Hindborg <[email protected]>
>> >> Signed-off-by: Andreas Hindborg <[email protected]>
>> >
>> >> +///         let result = NonNull::new(KBox::into_raw(result))
>> >> +///             .expect("Raw pointer to newly allocation KBox is null, 
>> >> this should never happen.");
>> >
>> > KBox should probably have an into_raw_nonnull().
>>
>> I can add that.
>>
>> >
>> >> +///    let foo = Foo::new().expect("Failed to allocate a Foo. This 
>> >> shouldn't happen");
>> >> +///    assert!(*FOO_ALLOC_COUNT.lock() == 1);
>> >
>> > Use ? here.
>>
>> Ok.
>>
>> >
>> >> +/// }
>> >> +/// // `foo` is out of scope now, so we expect no live allocations.
>> >> +/// assert!(*FOO_ALLOC_COUNT.lock() == 0);
>> >> +/// ```
>> >> +pub unsafe trait Ownable {
>> >> +    /// Releases the object.
>> >> +    ///
>> >> +    /// # Safety
>> >> +    ///
>> >> +    /// Callers must ensure that:
>> >> +    /// - `this` points to a valid `Self`.
>> >> +    /// - `*this` is no longer used after this call.
>> >> +    unsafe fn release(this: NonNull<Self>);
>> >
>> > Honestly, not using it after this call may be too strong. I can imagine
>> > wanting a value where I have both an ARef<_> and Owned<_> reference to
>> > something similar to the existing Arc<_>/ListArc<_> pattern, and in that
>> > case the value may in fact be accessed after this call if you still have
>> > an ARef<_>.
>>
>> I do not understand your use case.
>>
>> You are not supposed to have both an `ARef` and an `Owned` at the same
>> time. The `Owned` is to `ARef` what `UniqueArc` is to `Arc`. It is
>> supposed to be unique and no `ARef` can be live while the `Owned` is
>> live.
>>
>> A `ListArc` is "at most one per list link" and it takes a refcount on
>> the object by owning an `Arc`. As far as I recall, it does not provide
>> mutable access to anything but the list link. To me, that is a very
>> different situation.
>
> I mean, even Page is kind of an example like that.
>
> Pages are refcounted, but when you have a higher-order page, the
> __free_pages() call does something special beyond what put_page(). For
> example, if you have an order-2 page, which consists of 4 pages, then
> the refcount only keeps the first page alive, and __free_pages() frees
> the 3 extra pages right away even if refcount is still non-zero. The
> first page then stays alive until the last put_page() is called.

I see. We currently only support order 0 pages. I think we can handle
this situation later, if we need to handle higher order pages.

In that case, we could hand out `Owned<Page>` for the head page and then
provide some way of getting a `&Page` for the tail pages. Obtaining
`Owned<Page>` for a tail page does not make sense.

More likely we will build an abstraction for `struct folio`. We can
still hand some kind of page reference for tail pages from an `Owned<Folio>`.

Best regards,
Andreas Hindborg


Reply via email to