rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Oliver Mangold <oliver.mangold@pm.me>
To: "Benoît du Garreau" <benoit@dugarreau.fr>
Cc: "Benoît du Garreau" <bdgdlm@outlook.com>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org
Subject: Re: [PATCH] rust: adding UniqueRefCounted and UniqueRef types
Date: Sat, 01 Mar 2025 08:06:49 +0000	[thread overview]
Message-ID: <Z8LAFz_Q07qhio-O@laptop> (raw)
In-Reply-To: <20250228234148.7270-1-benoit@dugarreau.fr>

On 250301 0041, Benoît du Garreau wrote:
> From: Benoît du Garreau <bdgdlm@outlook.com>
> 
> It would be great for this trait to only have a `is_unique` method, and that functions here
> do the actual work. It would make it easier to implement and would avoid duplicating this
> work.
Hi,

I see where you are coming from, but there are good reasons for it to be like this.

mq::Request (for which this work was initially done) has the surprising property,
that it is possible to create a reference to it 'out of band'
(i.e. without deriving it from an existing one) through mq::TagSet::tag_to_rq().

As this means try_shared_to_unique() to an UniqueRef can race
with tag_to_rq(), a non-standard reference counting scheme needs to be used
which can distinguish between 'a single ARef exists' and 'an UniqueRef exists',
and requires the is_unique() check and the necessary modification of the
reference count in try_shared_to_unique() have to be done
in one combined atomic operation.

Of course the whole thing could be refactored that both ways work, this one
and one like you suggest with just a to_unique(). I will think about it
for a bit, but I'm not sure it is worth the effort.

What probably makes sense is to at least have a default implementation
for unique_to_shared() which just does a
ARef::from_raw(UniqueRef::into_raw()) leaving only try_shared_to_unique()
as mandatory to implemented.

Thoughts?
> Maybe this could even be a new method on `AlwaysRefCounted`?
>
I didn't do that intentionally, because I think for many AlwaysRefCounted
implementors it would be a pain, as they simply use some get() and put()
methods to inc/dec the refcount which are provided by the C API,
while the actual refcount stays hidden from them.
> 
> I think you meant "no other refcount" or "only references borrowed from this".
>
Yes, you are right. Thanks. I will fix that.
> 
> `UniqueRef` is essentially a `Box`, so it should have the same `Send`/`Sync` implementations. Here
> I don't see how sending a `UniqueRef<T>` is sharing a `&T`.
> 
> Same here: you can only get a `&T` from a `UniqueRef<T>`, definitely not clone it.
>
I just copy/pasted that from ARef. You might be right, I have to think about that when
my minds is less foggy than right now :)
> > +
> > +
> > +impl<T: UniqueRefCounted> From<&T> for UniqueRef<T> {
> > +    /// Converts the [`UniqueRef`] into an [`ARef`]
> > +    /// by calling [`UniqueRefCounted::unique_to_shared`] on it.
> > +    fn from(b: &T) -> Self {
> > +        b.inc_ref();
> > +        // SAFETY: We just incremented the refcount above.
> > +        unsafe { Self::from_raw(NonNull::from(b)) }
> > +    }
> > +}
> 
> This is wrong: the reference borrows from a refcount (as per `AlwaysRefCounted`), and this
> method increments it once more. It cannot be unique when the function returns.
> Actually the only way such conversion could be written is by cloning `T`, which is probably
> not what we want.
> 
Good catch. That was also an relict of copy-paste which I missed. The method should
just be deleted. I will do that.

Best,

Oliver


  reply	other threads:[~2025-03-01  8:06 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-28 14:43 [PATCH] rust: adding UniqueRefCounted and UniqueRef types Oliver Mangold
2025-02-28 15:21 ` Miguel Ojeda
2025-02-28 15:54 ` Boqun Feng
2025-02-28 18:01 ` [PATCH v2] " Oliver Mangold
2025-02-28 18:09   ` Boqun Feng
2025-02-28 18:16     ` Boqun Feng
2025-02-28 18:29   ` Andreas Hindborg
2025-03-03 13:29     ` [PATCH v3] " Oliver Mangold
2025-03-03 14:22       ` Andreas Hindborg
2025-03-03 16:33         ` Oliver Mangold
2025-03-03 14:09   ` [PATCH v2] " Andreas Hindborg
2025-02-28 23:41 ` [PATCH] " Benoît du Garreau
2025-03-01  8:06   ` Oliver Mangold [this message]
  -- strict thread matches above, loose matches on Subject: below --
2025-02-28 16:06 Oliver Mangold
2025-02-28 16:21 ` Boqun Feng
2025-02-28 16:52 ` Miguel Ojeda

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=Z8LAFz_Q07qhio-O@laptop \
    --to=oliver.mangold@pm.me \
    --cc=a.hindborg@kernel.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=bdgdlm@outlook.com \
    --cc=benno.lossin@proton.me \
    --cc=benoit@dugarreau.fr \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=gary@garyguo.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tmgross@umich.edu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).