diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2016-07-07 11:46:09 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2016-07-12 12:51:13 -0700 |
| commit | a7220d9046e292869dded2c478544850c220c7de (patch) | |
| tree | 3f67e79f8fd97c84d5156bae36298ed9f54c1639 /src/libstd/sys/common | |
| parent | 31e9ed5d6cf567557d2219add7afedae93aaf2a5 (diff) | |
std: Clean out deprecated APIs
This primarily removes a lot of `sync::Static*` APIs and rejiggers the associated implementations. While doing this it was discovered that the `is_poisoned` method can actually result in a data race for the Mutex/RwLock primitives, so the inner `Cell<bool>` was changed to an `AtomicBool` to prevent the associated data race. Otherwise the usage/gurantees should be the same they were before.
Diffstat (limited to 'src/libstd/sys/common')
| -rw-r--r-- | src/libstd/sys/common/poison.rs | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs index 83780a31cce..55212bf35d6 100644 --- a/src/libstd/sys/common/poison.rs +++ b/src/libstd/sys/common/poison.rs @@ -8,22 +8,28 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use cell::Cell; use error::{Error}; use fmt; use marker::Reflect; +use sync::atomic::{AtomicBool, Ordering}; use thread; -pub struct Flag { failed: Cell<bool> } +pub struct Flag { failed: AtomicBool } -// This flag is only ever accessed with a lock previously held. Note that this -// a totally private structure. -unsafe impl Send for Flag {} -unsafe impl Sync for Flag {} +// Note that the Ordering uses to access the `failed` field of `Flag` below is +// always `Relaxed`, and that's because this isn't actually protecting any data, +// it's just a flag whether we've panicked or not. +// +// The actual location that this matters is when a mutex is **locked** which is +// where we have external synchronization ensuring that we see memory +// reads/writes to this flag. +// +// As a result, if it matters, we should see the correct value for `failed` in +// all cases. impl Flag { pub const fn new() -> Flag { - Flag { failed: Cell::new(false) } + Flag { failed: AtomicBool::new(false) } } #[inline] @@ -39,13 +45,13 @@ impl Flag { #[inline] pub fn done(&self, guard: &Guard) { if !guard.panicking && thread::panicking() { - self.failed.set(true); + self.failed.store(true, Ordering::Relaxed); } } #[inline] pub fn get(&self) -> bool { - self.failed.get() + self.failed.load(Ordering::Relaxed) } } |
