-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Allow to check if sync::Once is already initialized #53027
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
r? @shepmaster (rust_highfive has picked a reviewer for you, use r? to override) |
/// assert!(handle.join().is_err()); | ||
/// assert_eq!(INIT.is_completed(), false); | ||
/// ``` | ||
#[unstable(feature = "once_is_completed", issue = "42")] |
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.
Isn't this issue number wrong? Issue #42 seems totally irrelevant to this code.
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.
It's a placeholder, there's no tracking issue for this yet
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.
Well, I just found that 42
is the answer to everything, however I still hope it could be replaced by the relevant issue ^v^
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.
As soon as @rust-lang/libs decides that we indeed want this feature and creates a tracking issue, I'll update the PR.
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.
Thanks for the explanation!
Here's a somewhat better comparison which explains why
|
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 feels like a highly abusable / misusable feature from the outside looking in. With such a function, I can see people wrapping their usages of Once
with an extra guard "for the fast path". I don't know if that's a real concern or even if it would be an antipattern, but maybe you could chime in on that a bit?
/// | ||
/// static INIT: Once = Once::new(); | ||
/// | ||
/// assert_eq!(INIT.is_completed(), false); |
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.
Think these would normally be written as assert!(INIT.is_completed())
/ assert!(!INIT.is_completed())
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 think for boolean-returning methods writing an assert_eq!
in docs specifically helps a bit with readability. Here's an example from result:
https://doc.rust-lang.org/std/result/enum.Result.html#method.is_ok
src/libstd/sync/once.rs
Outdated
/// ``` | ||
#[unstable(feature = "once_is_completed", issue = "42")] | ||
pub fn is_completed(&self) -> bool { | ||
self.state.load(Ordering::Acquire) == COMPLETE |
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'm never smart enough to use any ordering besides SeqCst
, but perhaps you can explain why this ordering is appropriate to whoever is clever enough to understand?
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 point! Reshuffled the code a bit to reuse an existing comment :-)
Passing on to someone smarter... r? @Kimundi |
Interesting point! It is indeed would be an anti pattern! However, I believe there are cases where you really need to check if once is initialized, without actually initializing it. For example, a |
I've also got feature requests for such functionality in the past in @rfcbot fcp merge |
Team member @Kimundi has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
@rfcbot document the race condition I think there is a potential race condition:
This race is probably fine in some cases. I think it is in the use case described by #53027 (comment). But still, this should be mentioned in the doc-comment to try and make callers aware of it. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
959f88a
to
e1bd0e7
Compare
Yup, added this case to the doc. Ideally, these all should be formulated in terms of "happens before", but I can't find a short way to express that. As a non-native speaker, I am also not sure whether it should be |
|
In this case, the intuition I usually try to convey is that the return value is outdated. So people should think of Maybe it should be called |
Oops I messed up the rcfbot command to formally register my concern. But that’s ok, since my concern is resolved now. Thanks! |
The final comment period, with a disposition to merge, as per the review above, is now complete. |
Ping from triage @Kimundi! The FCP ended. |
Ping from triage @Kimundi / @rust-lang/libs: This PR requires your review. |
@bors: r+ I'm gonna go ahead and r+ this to merge but we can of course continue to bikeshed the name while it's unstable! |
📌 Commit e1bd0e7 has been approved by |
Allow to check if sync::Once is already initialized Hi! I propose to expose a way to check if a `Once` instance is initialized. I need it in `once_cell`. `OnceCell` is effetively a pair of `(Once, UnsafeCell<Option<T>>)`, which can set the `T` only once. Because I can't check if `Once` is initialized, I am forced to add an indirection and check the value of ptr instead: https://github.com/matklad/once_cell/blob/8127a81976c3f2f4c0860562c3f14647ebc025c0/src/lib.rs#L423-L429 https://github.com/matklad/once_cell/blob/8127a81976c3f2f4c0860562c3f14647ebc025c0/src/lib.rs#L457-L461 The `parking_lot`'s version of `Once` exposes the state as an enum: https://docs.rs/parking_lot/0.6.3/parking_lot/struct.Once.html#method.state. I suggest, for now, just to add a simple `bool` function: this fits my use-case perfectly, exposes less implementation details, and is forward-compatible with more fine-grained state checking.
☀️ Test successful - status-appveyor, status-travis |
/// assert_eq!(INIT.is_completed(), false); | ||
/// ``` | ||
#[unstable(feature = "once_is_completed", issue = "42")] | ||
pub fn is_completed(&self) -> bool { |
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.
Once
is not generic, so this is missing an #[inline]
. (@anp found a rayon bench regression likely caused by 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.
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.
@eddyb is that documented in the api guidelines or somewhere similar?
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.
Fixed in #54662
Fix tracking issue for Once::is_completed rust-lang#53027 was merged without a tracking issue. I just filed rust-lang#54890. CC @matklad
Fix tracking issue for Once::is_completed rust-lang#53027 was merged without a tracking issue. I just filed rust-lang#54890. CC @matklad
Fix tracking issue for Once::is_completed rust-lang#53027 was merged without a tracking issue. I just filed rust-lang#54890. CC @matklad
Fix tracking issue for Once::is_completed rust-lang#53027 was merged without a tracking issue. I just filed rust-lang#54890. CC @matklad
Hi!
I propose to expose a way to check if a
Once
instance is initialized.I need it in
once_cell
.OnceCell
is effetively a pair of(Once, UnsafeCell<Option<T>>)
, which can set theT
only once. Because I can't check ifOnce
is initialized, I am forced to add an indirection and check the value of ptr instead:https://github.com/matklad/once_cell/blob/8127a81976c3f2f4c0860562c3f14647ebc025c0/src/lib.rs#L423-L429
https://github.com/matklad/once_cell/blob/8127a81976c3f2f4c0860562c3f14647ebc025c0/src/lib.rs#L457-L461
The
parking_lot
's version ofOnce
exposes the state as an enum: https://docs.rs/parking_lot/0.6.3/parking_lot/struct.Once.html#method.state.I suggest, for now, just to add a simple
bool
function: this fits my use-case perfectly, exposes less implementation details, and is forward-compatible with more fine-grained state checking.