-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Rework Rc and Arc APIs for FCP #27837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/liballoc/rc.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This calls clone() in some cases where it isn't necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case where self is the only strong pointer, but there are other weak pointers, you can just ptr::read the value out of the old Rc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's only one strong pointer (this one) but many weak pointers then you can move ownership from the original Rc to a new one, thereby destroying the original one (decrementing its strong count to 0).
I believe Arc takes this strategy currently.
9c3cf0c to
86bbc3d
Compare
src/liballoc/rc.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn’t this be 1 rather than 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
god damnit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should probably focus on this patch at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pleased to announce the tests caught this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good tests :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Err, no they didn't, try_unwrap just had an out of date test.
This is actually technically correct. Just weird to say. (The check is really > 1, where 0 is a nonsense value) -- it's needlessly ineffecient though.
ebd3c6e to
777dd7c
Compare
|
☔ The latest upstream changes (presumably #27818) made this pull request unmergeable. Please resolve the merge conflicts. |
|
Just out of curiosity, why is it preferable to have |
|
@glaebhoerl when working with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this can be replaced with an Acquire on the CAS and no fence, because this operation will only succeed if we're the last one out. (Similar to what we do for make_mut.)
- Normally we fence after only if we see we're the last one, but doing the
Acquireas part of the operation is slightly more efficient in some architectures. - Since this only succeeds if we're the last strong ref, the
Releaseisn't needed; there's no one who would do a correspondingAcquire.
(That said, this is fine as-is; you could treat these as optimizations to be done later.)
|
Hey, sorry for the delay reviewing this. Overall, this seems like a pretty good direction for the API (e.g.,
Anyway, basically, r=me. |
|
📌 Commit 9a0db5b has been approved by |
* Add `Rc::would_unwrap(&Self) -> bool` to introspect whether try_unwrap would succeed, because it's destructive (unlike get_mut). * Move `rc.downgrade()` to `Rc::downgrade(&Self)` per conventions. * Deprecate `Rc::weak_count` and `Rc::strong_count` for questionable utility. * Deprecate `Rc::is_unique` for questionable semantics (there are two kinds of uniqueness with Weak pointers in play). * Rename `rc.make_unique()` to `Rc::make_mut(&mut Self)` per conventions, to avoid uniqueness terminology, and to clarify the relation to `Rc::get_mut`.
* Add previously omitted function `Arc::try_unwrap(Self) -> Result<T, Self>` * Move `arc.downgrade()` to `Arc::downgrade(&Self)` per conventions. * Deprecate `Arc::weak_count` and `Arc::strong_count` for raciness. It is almost impossible to correctly act on these results without a CAS loop on the actual fields. * Rename `Arc::make_unique` to `Arc::make_mut` to avoid uniqueness terminology and to clarify relation to `Arc::get_mut`.
|
@bors r=aturon (rebasing error) |
|
📌 Commit 4c8d75f has been approved by |
That reminds me, do the docs mention the |
|
@SimonSapin Nope, definitely a good follow up. |
This prepares both for the FCP of #27718 Arc: * Add previously omitted function `Arc::try_unwrap(Self) -> Result<T, Self>` * Move `arc.downgrade()` to `Arc::downgrade(&Self)` per conventions. * Deprecate `Arc::weak_count` and `Arc::strong_count` for raciness. It is almost impossible to correctly act on these results without a CAS loop on the actual fields. * Rename `Arc::make_unique` to `Arc::make_mut` to avoid uniqueness terminology and to clarify relation to `Arc::get_mut`. Rc: * Add `Rc::would_unwrap(&Self) -> bool` to introspect whether try_unwrap would succeed, because it's destructive (unlike get_mut). * Move `rc.downgrade()` to `Rc::downgrade(&Self)` per conventions. * Deprecate `Rc::weak_count` and `Rc::strong_count` for questionable utility. * Deprecate `Rc::is_unique` for questionable semantics (there are two kinds of uniqueness with Weak pointers in play). * Rename `rc.make_unique()` to `Rc::make_mut(&mut Self)` per conventions, to avoid uniqueness terminology, and to clarify the relation to `Rc::get_mut`. Notable omission: * Arc::would_unwrap is not added due to the fact that it's racy, and therefore doesn't provide much actionable information. (note: rc_would_unwrap is not proposed for FCP as it is truly experimental) r? @aturon (careful attention needs to be taken for the new Arc::try_unwrap, but intuitively it should "just work" by virtue of being semantically equivalent to Drop).
|
Hm looks like our android slave never came back after I tried last time, but this passed all tests otherwise so merging manually |
This prepares both for the FCP of #27718
Arc:
Arc::try_unwrap(Self) -> Result<T, Self>arc.downgrade()toArc::downgrade(&Self)per conventions.Arc::weak_countandArc::strong_countfor raciness. It is almostimpossible to correctly act on these results without a CAS loop on the actual
fields.
Arc::make_uniquetoArc::make_mutto avoid uniqueness terminologyand to clarify relation to
Arc::get_mut.Rc:
Rc::would_unwrap(&Self) -> boolto introspect whether try_unwrap would succeed,because it's destructive (unlike get_mut).
rc.downgrade()toRc::downgrade(&Self)per conventions.Rc::weak_countandRc::strong_countfor questionable utility.Rc::is_uniquefor questionable semantics (there are two kinds ofuniqueness with Weak pointers in play).
rc.make_unique()toRc::make_mut(&mut Self)per conventions, toavoid uniqueness terminology, and to clarify the relation to
Rc::get_mut.Notable omission:
provide much actionable information.
(note: rc_would_unwrap is not proposed for FCP as it is truly experimental)
r? @aturon (careful attention needs to be taken for the new Arc::try_unwrap, but intuitively it should "just work" by virtue of being semantically equivalent to Drop).