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 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.