Open
Description
Is this code sound?
// Represents an abstract type with safety invariants
struct Corruptee { is_corrupted: bool }
impl Corruptee {
// SAFETY: must be non-corrupted
unsafe fn witness_uncorrupted(&self) {
unsafe { core::hint::assert_unchecked(!self.is_corrupted) }
}
fn corrupt(&mut self) { self.is_corrupted = true; }
fn uncorrupt(&mut self) { self.is_corrupted = false; }
}
struct Worker {
corruptee: Mutex<Corruptee>,
}
impl Worker {
fn do_work(&self, f: impl FnOnce()) {
let mut corruptee = self.corruptee.lock().expect("poisoned");
// SAFETY: `corruptee` can only be corrupted if `f` has ever panicked, but if it did, the
// mutex would be poisoned and `expect` would panic.
unsafe {
corruptee.witness_uncorrupted();
}
corruptee.corrupt();
f();
corruptee.uncorrupt();
}
}
I'm aware that poisoning is advisory in the sense that anyone with access to the Mutex
can remove the poison if they wish. But in this example, Mutex
is never revealed to users of the safe abstraction, and is only used an implementation detail.
Do we want to guarantee that poisoning can be relied upon for safety, like in this example, and never has false negatives?
I'm asking because mutex poisoning doesn't always work currently. But it's also never explicitly documented to be best-effort.
@rustbot label +A-concurrency +C-discussion +T-libs-api
(If poisoning was considered reliable, this would be T-libs I-unsound.)
Metadata
Metadata
Assignees
Labels
Area: ConcurrencyCategory: Discussion or questions that doesn't represent real issues.Nominated for discussion during a libs-api team meeting.Nominated for discussion during a libs team meeting.Relevant to the library API team, which will review and decide on the PR/issue.This issue may need triage. Remove it if it has been sufficiently triaged.