-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Allow to check if sync::Once is already initialized #53027
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.