From f3a7ec7028c76b3a1c6051131328f372b068e33a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 29 Dec 2014 15:03:01 -0800 Subject: std: Second pass stabilization of sync This pass performs a second pass of stabilization through the `std::sync` module, avoiding modules/types that are being handled in other PRs (e.g. mutexes, rwlocks, condvars, and channels). The following items are now stable * `sync::atomic` * `sync::atomic::ATOMIC_BOOL_INIT` (was `INIT_ATOMIC_BOOL`) * `sync::atomic::ATOMIC_INT_INIT` (was `INIT_ATOMIC_INT`) * `sync::atomic::ATOMIC_UINT_INIT` (was `INIT_ATOMIC_UINT`) * `sync::Once` * `sync::ONCE_INIT` * `sync::Once::call_once` (was `doit`) * C == `pthread_once(..)` * Boost == `call_once(..)` * Windows == `InitOnceExecuteOnce` * `sync::Barrier` * `sync::Barrier::new` * `sync::Barrier::wait` (now returns a `bool`) * `sync::Semaphore::new` * `sync::Semaphore::acquire` * `sync::Semaphore::release` The following items remain unstable * `sync::SemaphoreGuard` * `sync::Semaphore::access` - it's unclear how this relates to the poisoning story of mutexes. * `sync::TaskPool` - the semantics of a failing task and whether a thread is re-attached to a thread pool are somewhat unclear, and the utility of this type in `sync` is question with respect to the jobs of other primitives. This type will likely become stable or move out of the standard library over time. * `sync::Future` - futures as-is have yet to be deeply re-evaluated with the recent core changes to Rust's synchronization story, and will likely become stable in the future but are unstable until that time comes. [breaking-change] --- src/libstd/rt/backtrace.rs | 2 +- src/libstd/rt/exclusive.rs | 119 --------------------------------------------- src/libstd/rt/unwind.rs | 20 ++++---- src/libstd/rt/util.rs | 2 +- 4 files changed, 12 insertions(+), 131 deletions(-) delete mode 100644 src/libstd/rt/exclusive.rs (limited to 'src/libstd/rt') diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index 3eeb0ad3968..0b69486129a 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -22,7 +22,7 @@ pub use sys::backtrace::write; // For now logging is turned off by default, and this function checks to see // whether the magical environment variable is present to see if it's turned on. pub fn log_enabled() -> bool { - static ENABLED: atomic::AtomicInt = atomic::INIT_ATOMIC_INT; + static ENABLED: atomic::AtomicInt = atomic::ATOMIC_INT_INIT; match ENABLED.load(atomic::SeqCst) { 1 => return false, 2 => return true, diff --git a/src/libstd/rt/exclusive.rs b/src/libstd/rt/exclusive.rs deleted file mode 100644 index 88bdb29caec..00000000000 --- a/src/libstd/rt/exclusive.rs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::prelude::*; - -use cell::UnsafeCell; -use rt::mutex; - -/// An OS mutex over some data. -/// -/// This is not a safe primitive to use, it is unaware of the libgreen -/// scheduler, as well as being easily susceptible to misuse due to the usage of -/// the inner NativeMutex. -/// -/// > **Note**: This type is not recommended for general use. The mutex provided -/// > as part of `libsync` should almost always be favored. -pub struct Exclusive { - lock: mutex::NativeMutex, - data: UnsafeCell, -} - -unsafe impl Send for Exclusive { } - -unsafe impl Sync for Exclusive { } - -/// An RAII guard returned via `lock` -pub struct ExclusiveGuard<'a, T:'a> { - // FIXME #12808: strange name to try to avoid interfering with - // field accesses of the contained type via Deref - _data: &'a mut T, - _guard: mutex::LockGuard<'a>, -} - -impl Exclusive { - /// Creates a new `Exclusive` which will protect the data provided. - pub fn new(user_data: T) -> Exclusive { - Exclusive { - lock: unsafe { mutex::NativeMutex::new() }, - data: UnsafeCell::new(user_data), - } - } - - /// Acquires this lock, returning a guard which the data is accessed through - /// and from which that lock will be unlocked. - /// - /// This method is unsafe due to many of the same reasons that the - /// NativeMutex itself is unsafe. - pub unsafe fn lock<'a>(&'a self) -> ExclusiveGuard<'a, T> { - let guard = self.lock.lock(); - let data = &mut *self.data.get(); - - ExclusiveGuard { - _data: data, - _guard: guard, - } - } -} - -impl<'a, T: Send> ExclusiveGuard<'a, T> { - // The unsafety here should be ok because our loan guarantees that the lock - // itself is not moving - pub fn signal(&self) { - unsafe { self._guard.signal() } - } - pub fn wait(&self) { - unsafe { self._guard.wait() } - } -} - -impl<'a, T: Send> Deref for ExclusiveGuard<'a, T> { - fn deref(&self) -> &T { &*self._data } -} -impl<'a, T: Send> DerefMut for ExclusiveGuard<'a, T> { - fn deref_mut(&mut self) -> &mut T { &mut *self._data } -} - -#[cfg(test)] -mod tests { - use prelude::*; - use sync::Arc; - use super::Exclusive; - use task; - - #[test] - fn exclusive_new_arc() { - unsafe { - let mut futures = Vec::new(); - - let num_tasks = 10; - let count = 10; - - let total = Arc::new(Exclusive::new(box 0)); - - for _ in range(0u, num_tasks) { - let total = total.clone(); - let (tx, rx) = channel(); - futures.push(rx); - - task::spawn(move || { - for _ in range(0u, count) { - **total.lock() += 1; - } - tx.send(()); - }); - }; - - for f in futures.iter_mut() { f.recv() } - - assert_eq!(**total.lock(), num_tasks * count); - } - } -} diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index e0c512706e6..a6063d0b609 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -84,15 +84,15 @@ pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: uint); // For more information, see below. const MAX_CALLBACKS: uint = 16; static CALLBACKS: [atomic::AtomicUint; MAX_CALLBACKS] = - [atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT, - atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT, - atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT, - atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT, - atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT, - atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT, - atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT, - atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT]; -static CALLBACK_CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT; + [atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT, + atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT, + atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT, + atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT, + atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT, + atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT, + atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT, + atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT]; +static CALLBACK_CNT: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT; thread_local! { static PANICKING: Cell = Cell::new(false) } @@ -544,7 +544,7 @@ fn begin_unwind_inner(msg: Box, file_line: &(&'static str, uint)) -> // Make sure the default failure handler is registered before we look at the // callbacks. static INIT: Once = ONCE_INIT; - INIT.doit(|| unsafe { register(failure::on_fail); }); + INIT.call_once(|| unsafe { register(failure::on_fail); }); // First, invoke call the user-defined callbacks triggered on thread panic. // diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index fee86e33455..d66d8d52be9 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -47,7 +47,7 @@ pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool { } pub fn min_stack() -> uint { - static MIN: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT; + static MIN: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT; match MIN.load(atomic::SeqCst) { 0 => {} n => return n - 1, -- cgit 1.4.1-3-g733a5