-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
std: Rewrite Once with poisoning #32325
Conversation
r? @aturon cc @rust-lang/libs |
Oooh, is this the first use of |
Nah unfortunately that trophy went to channels long ago :) |
/// this function will continue to attempt to call initialization functions | ||
/// until one of them doesn't panic. | ||
/// | ||
/// The closure `f` is yielded a boolean indicating whether this `Once` is |
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.
Is true
"I am poisoned", or "I am valid"?
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.
Probably an indicator that this should be an enum or an opaque struct! Currently it means "I'm poisoned"
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.
Agreed.
There is actually a use case for panicking in the |
8a69160
to
a3c3d8a
Compare
@Stebalien that's an interesting data point! When we discussed this at the libs triage meeting we didn't reach a firm conclusion about whether we were comfortable to move forward with this or not, so it's good to have this data! |
// primitive works now! | ||
// | ||
// So to recap, the guarantees of a Once are that it will call the | ||
// initialization closure exactly once, and it will never return until the one |
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.
s/exactly/at most/
a3c3d8a
to
00f6841
Compare
} | ||
|
||
// Run the initialization routine, letting it know if we're | ||
// poisoned or not, and then just return immediately after |
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.
Would be helpful for this comment to mention that Finish
does the wakeups.
Beautiful -- this is pretty much exactly what I imagined when we discussed the algorithm the other day. Just a couple minor nits -- would be good to introduce an enum/struct before landing, rather than having to do that adjustment later. With that, r=me. |
mutex: StaticMutex, | ||
cnt: AtomicIsize, | ||
lock_cnt: AtomicIsize, | ||
state: AtomicUsize, |
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 struct should have some PhantomData
describing the kind of data state
can point to. (Basically this should be done any time a pointer is hidden in a usize, so that auto traits etc work correctly.)
316c24e
to
a755a67
Compare
std: Rewrite Once with poisoning This commit rewrites the `std::sync::Once` primitive with poisoning in mind in light of rust-lang#31688. Currently a panic in the initialization closure will cause future initialization closures to run, but the purpose of a Once is usually to initialize some global state so it's highly likely that the global state is corrupt if a panic happened. The same strategy of a mutex is taken where a panic is propagated by default. A new API, `call_once_force`, was added to subvert panics like is available on Mutex as well (for when panicking is handled internally). Adding this support was a significant enough change to the implementation that it was just completely rewritten from scratch, primarily to avoid using a `StaticMutex` which needs to have `destroy()` called on it at some point (a pain to do). Closes rust-lang#31688
@bors r-
http://buildbot.rust-lang.org/builders/auto-linux-64-nopt-t/builds/8503/steps/test/logs/stdio |
This commit rewrites the `std::sync::Once` primitive with poisoning in mind in light of rust-lang#31688. Currently a panic in the initialization closure will cause future initialization closures to run, but the purpose of a Once is usually to initialize some global state so it's highly likely that the global state is corrupt if a panic happened. The same strategy of a mutex is taken where a panic is propagated by default. A new API, `call_once_force`, was added to subvert panics like is available on Mutex as well (for when panicking is handled internally). Adding this support was a significant enough change to the implementation that it was just completely rewritten from scratch, primarily to avoid using a `StaticMutex` which needs to have `destroy()` called on it at some point (a pain to do). Closes rust-lang#31688
a755a67
to
c966c33
Compare
std: Rewrite Once with poisoning This commit rewrites the `std::sync::Once` primitive with poisoning in mind in light of #31688. Currently a panic in the initialization closure will cause future initialization closures to run, but the purpose of a Once is usually to initialize some global state so it's highly likely that the global state is corrupt if a panic happened. The same strategy of a mutex is taken where a panic is propagated by default. A new API, `call_once_force`, was added to subvert panics like is available on Mutex as well (for when panicking is handled internally). Adding this support was a significant enough change to the implementation that it was just completely rewritten from scratch, primarily to avoid using a `StaticMutex` which needs to have `destroy()` called on it at some point (a pain to do). Closes #31688
Was this discussed further? (I've unfortunately missed quite a few libs meetings recently.) It seems like it might be worth providing a separate function something like |
@huonw IIRC, we decided that functionality like this can be easily added in the future if desired. |
This commit rewrites the
std::sync::Once
primitive with poisoning in mind inlight of #31688. Currently a panic in the initialization closure will cause
future initialization closures to run, but the purpose of a Once is usually to
initialize some global state so it's highly likely that the global state is
corrupt if a panic happened. The same strategy of a mutex is taken where a panic
is propagated by default.
A new API,
call_once_force
, was added to subvert panics like is available onMutex as well (for when panicking is handled internally).
Adding this support was a significant enough change to the implementation that
it was just completely rewritten from scratch, primarily to avoid using a
StaticMutex
which needs to havedestroy()
called on it at some point (a painto do).
Closes #31688