about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2016-07-07 11:46:09 -0700
committerAlex Crichton <alex@alexcrichton.com>2016-07-12 12:51:13 -0700
commita7220d9046e292869dded2c478544850c220c7de (patch)
tree3f67e79f8fd97c84d5156bae36298ed9f54c1639 /src/libstd/sys
parent31e9ed5d6cf567557d2219add7afedae93aaf2a5 (diff)
downloadrust-a7220d9046e292869dded2c478544850c220c7de.tar.gz
rust-a7220d9046e292869dded2c478544850c220c7de.zip
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')
-rw-r--r--src/libstd/sys/common/poison.rs24
-rw-r--r--src/libstd/sys/windows/backtrace.rs92
2 files changed, 64 insertions, 52 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)
     }
 }
 
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 0e10a8d8e8d..82a44c1c110 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -30,9 +30,9 @@ use io;
 use libc::c_void;
 use mem;
 use ptr;
-use sync::StaticMutex;
 use sys::c;
 use sys::dynamic_lib::DynamicLibrary;
+use sys::mutex::Mutex;
 
 macro_rules! sym {
     ($lib:expr, $e:expr, $t:ident) => (
@@ -101,53 +101,59 @@ impl Drop for Cleanup {
 pub fn write(w: &mut Write) -> io::Result<()> {
     // According to windows documentation, all dbghelp functions are
     // single-threaded.
-    static LOCK: StaticMutex = StaticMutex::new();
-    let _g = LOCK.lock();
+    static LOCK: Mutex = Mutex::new();
+    unsafe {
+        LOCK.lock();
+        let res = _write(w);
+        LOCK.unlock();
+        return res
+    }
+}
 
+unsafe fn _write(w: &mut Write) -> io::Result<()> {
     let dbghelp = match DynamicLibrary::open("dbghelp.dll") {
         Ok(lib) => lib,
         Err(..) => return Ok(()),
     };
-    unsafe {
-        // Fetch the symbols necessary from dbghelp.dll
-        let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
-        let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
-        let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
-
-        // Allocate necessary structures for doing the stack walk
-        let process = c::GetCurrentProcess();
-        let thread = c::GetCurrentThread();
-        let mut context: c::CONTEXT = mem::zeroed();
-        c::RtlCaptureContext(&mut context);
-        let mut frame: c::STACKFRAME64 = mem::zeroed();
-        let image = init_frame(&mut frame, &context);
-
-        // Initialize this process's symbols
-        let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
-        if ret != c::TRUE { return Ok(()) }
-        let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
-
-        // And now that we're done with all the setup, do the stack walking!
-        // Start from -1 to avoid printing this stack frame, which will
-        // always be exactly the same.
-        let mut i = -1;
-        write!(w, "stack backtrace:\n")?;
-        while StackWalk64(image, process, thread, &mut frame, &mut context,
-                          ptr::null_mut(),
-                          ptr::null_mut(),
-                          ptr::null_mut(),
-                          ptr::null_mut()) == c::TRUE {
-            let addr = frame.AddrPC.Offset;
-            if addr == frame.AddrReturn.Offset || addr == 0 ||
-               frame.AddrReturn.Offset == 0 { break }
-
-            i += 1;
-
-            if i >= 0 {
-                printing::print(w, i, addr - 1, process, &dbghelp)?;
-            }
-        }
 
-        Ok(())
+    // Fetch the symbols necessary from dbghelp.dll
+    let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
+    let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
+    let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
+
+    // Allocate necessary structures for doing the stack walk
+    let process = c::GetCurrentProcess();
+    let thread = c::GetCurrentThread();
+    let mut context: c::CONTEXT = mem::zeroed();
+    c::RtlCaptureContext(&mut context);
+    let mut frame: c::STACKFRAME64 = mem::zeroed();
+    let image = init_frame(&mut frame, &context);
+
+    // Initialize this process's symbols
+    let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
+    if ret != c::TRUE { return Ok(()) }
+    let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
+
+    // And now that we're done with all the setup, do the stack walking!
+    // Start from -1 to avoid printing this stack frame, which will
+    // always be exactly the same.
+    let mut i = -1;
+    write!(w, "stack backtrace:\n")?;
+    while StackWalk64(image, process, thread, &mut frame, &mut context,
+                      ptr::null_mut(),
+                      ptr::null_mut(),
+                      ptr::null_mut(),
+                      ptr::null_mut()) == c::TRUE {
+        let addr = frame.AddrPC.Offset;
+        if addr == frame.AddrReturn.Offset || addr == 0 ||
+           frame.AddrReturn.Offset == 0 { break }
+
+        i += 1;
+
+        if i >= 0 {
+            printing::print(w, i, addr - 1, process, &dbghelp)?;
+        }
     }
+
+    Ok(())
 }