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
next prev parent 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).