-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Add functions to un-poison Mutex and RwLock #96422
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
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
538c984
to
fc38388
Compare
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.
Nice, this looks good to me.
Could you please make a tracking issue and update the unstable
attributes with the issue number?
I have created a tracking issue and updated the |
Reassigning to Mara at her request to look at how this fits in with "plans". r? @m-ou-se |
One thing I notice from looking at this a second time is it's not great RwLock unpoison only works if you have a write guard. If you have a read guard, you'd be out of luck. match rwlock.read() {
Ok(_) => …,
Err(poison_error) => {
let guard = poison_error.into_inner();
/* :( */ //RwLock::clear_poison(&guard);
// instead we have to do:
drop(guard);
let another_guard = rwlock.write().unwrap_err().into_inner(); // probably still poisoned (?)
RwLock::clear_poison(&another_guard);
drop(another_guard);
// back to read, since we didn't actually want write to begin with
let yet_another = rwlock.read().unwrap(); // probably not already re-poisoned (?)
// now we can finally read
}
} |
I have a few thoughts:
|
I like the simplicity of just I wonder how big of a pitfall that is in practice though, considering how the code would be structured. I imagine most usages would look something like this: let x = m.lock().unwrap_or_else(|e| {
e.get_mut().corrupted_state.reset();
m.clear_poison();
e.into_inner()
});
x.stuff.do_something();
// (implicit) drop(x); That is, first handle the poison, and then continue using it afterwards for the reason you attempted to lock it. This would make it hard to put The only other possible pitfall I can imagine is folks doing |
Another option could be to add it as a method on let x = m.lock().unwrap_or_else(|e| {
e.get_mut().corrupted_state.reset();
e.clear_poison()
});
x.stuff.do_something();
// (implicit) drop(x); |
I'd be fine with any of those approaches. |
@dtolnay What do you think? |
We discussed this in the libs-api meeting just now, and we agreed that we should go forward with (If the pattern of clearing poison right before doing PoisonError::into_inner() turns out to be a common one, we could consider PoisonError::clear_poison() as a short-hand for that pattern, but that would be a separate proposal.) |
I've updated the PR to take &self instead of a guard. |
Thanks! The doc comments still refer to the guards though. Can you update that too? |
oh, oops, yeah, I can update that. |
Thanks! @bors r+ |
📌 Commit a65afd8 has been approved by |
☀️ Test successful - checks-actions |
Finished benchmarking commit (cd73afa): comparison url. Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results
CyclesResults
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression Footnotes |
Feature is needed?
|
See discussion at https://internals.rust-lang.org/t/unpoisoning-a-mutex/16521/3