diff options
| author | bors <bors@rust-lang.org> | 2015-05-08 01:32:59 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-05-08 01:32:59 +0000 |
| commit | cf76e637450a861e94ef583340b8f080379a159a (patch) | |
| tree | f01e7c305dbe832c5283d229168223c5e8a24cf7 /src/libstd/sys/common | |
| parent | b402c43f088882db8a03bfcbb5eb8429ef7def0e (diff) | |
| parent | 7529bd60c3cbc4c7b635ee43a89d5b14f6fb8bf7 (diff) | |
| download | rust-cf76e637450a861e94ef583340b8f080379a159a.tar.gz rust-cf76e637450a861e94ef583340b8f080379a159a.zip | |
Auto merge of #25136 - alexcrichton:drop-the-two, r=aturon
* Remove the 2-suffix from some modules * Remove some unused files * Remove double-boxing for `ReentrantMutex`
Diffstat (limited to 'src/libstd/sys/common')
| -rw-r--r-- | src/libstd/sys/common/helper_thread.rs | 170 | ||||
| -rw-r--r-- | src/libstd/sys/common/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/common/net.rs (renamed from src/libstd/sys/common/net2.rs) | 0 | ||||
| -rw-r--r-- | src/libstd/sys/common/remutex.rs | 18 |
4 files changed, 12 insertions, 178 deletions
diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs deleted file mode 100644 index 34a58f6c83a..00000000000 --- a/src/libstd/sys/common/helper_thread.rs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2013-2014 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 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Implementation of the helper thread for the timer module -//! -//! This module contains the management necessary for the timer worker thread. -//! This thread is responsible for performing the send()s on channels for timers -//! that are using channels instead of a blocking call. -//! -//! The timer thread is lazily initialized, and it's shut down via the -//! `shutdown` function provided. It must be maintained as an invariant that -//! `shutdown` is only called when the entire program is finished. No new timers -//! can be created in the future and there must be no active timers at that -//! time. - -use prelude::v1::*; - -use boxed; -use cell::UnsafeCell; -use rt; -use sync::{StaticMutex, StaticCondvar}; -use sync::mpsc::{channel, Sender, Receiver}; -use sys::helper_signal; - -use thread; - -/// A structure for management of a helper thread. -/// -/// This is generally a static structure which tracks the lifetime of a helper -/// thread. -/// -/// The fields of this helper are all public, but they should not be used, this -/// is for static initialization. -pub struct Helper<M:Send> { - /// Internal lock which protects the remaining fields - pub lock: StaticMutex, - pub cond: StaticCondvar, - - // You'll notice that the remaining fields are UnsafeCell<T>, and this is - // because all helper thread operations are done through &self, but we need - // these to be mutable (once `lock` is held). - - /// Lazily allocated channel to send messages to the helper thread. - pub chan: UnsafeCell<*mut Sender<M>>, - - /// OS handle used to wake up a blocked helper thread - pub signal: UnsafeCell<usize>, - - /// Flag if this helper thread has booted and been initialized yet. - pub initialized: UnsafeCell<bool>, - - /// Flag if this helper thread has shut down - pub shutdown: UnsafeCell<bool>, -} - -unsafe impl<M:Send> Send for Helper<M> { } - -unsafe impl<M:Send> Sync for Helper<M> { } - -struct RaceBox(helper_signal::signal); - -unsafe impl Send for RaceBox {} -unsafe impl Sync for RaceBox {} - -macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => ( - static $name: Helper<$m> = Helper { - lock: ::sync::MUTEX_INIT, - cond: ::sync::CONDVAR_INIT, - chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> }, - signal: ::cell::UnsafeCell { value: 0 }, - initialized: ::cell::UnsafeCell { value: false }, - shutdown: ::cell::UnsafeCell { value: false }, - }; -) } - -impl<M: Send> Helper<M> { - /// Lazily boots a helper thread, becoming a no-op if the helper has already - /// been spawned. - /// - /// This function will check to see if the thread has been initialized, and - /// if it has it returns quickly. If initialization has not happened yet, - /// the closure `f` will be run (inside of the initialization lock) and - /// passed to the helper thread in a separate task. - /// - /// This function is safe to be called many times. - pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receiver<M>, T)) where - T: Send + 'static, - F: FnOnce() -> T, - { - unsafe { - let _guard = self.lock.lock().unwrap(); - if *self.chan.get() as usize == 0 { - let (tx, rx) = channel(); - *self.chan.get() = boxed::into_raw(box tx); - let (receive, send) = helper_signal::new(); - *self.signal.get() = send as usize; - - let receive = RaceBox(receive); - - let t = f(); - thread::spawn(move || { - helper(receive.0, rx, t); - let _g = self.lock.lock().unwrap(); - *self.shutdown.get() = true; - self.cond.notify_one() - }); - - let _ = rt::at_exit(move || { self.shutdown() }); - *self.initialized.get() = true; - } else if *self.chan.get() as usize == 1 { - panic!("cannot continue usage after shutdown"); - } - } - } - - /// Sends a message to a spawned worker thread. - /// - /// This is only valid if the worker thread has previously booted - pub fn send(&'static self, msg: M) { - unsafe { - let _guard = self.lock.lock().unwrap(); - - // Must send and *then* signal to ensure that the child receives the - // message. Otherwise it could wake up and go to sleep before we - // send the message. - assert!(*self.chan.get() as usize != 0); - assert!(*self.chan.get() as usize != 1, - "cannot continue usage after shutdown"); - (**self.chan.get()).send(msg).unwrap(); - helper_signal::signal(*self.signal.get() as helper_signal::signal); - } - } - - fn shutdown(&'static self) { - unsafe { - // Shut down, but make sure this is done inside our lock to ensure - // that we'll always receive the exit signal when the thread - // returns. - let mut guard = self.lock.lock().unwrap(); - - let ptr = *self.chan.get(); - if ptr as usize == 1 { - panic!("cannot continue usage after shutdown"); - } - // Close the channel by destroying it - let chan = Box::from_raw(*self.chan.get()); - *self.chan.get() = 1 as *mut Sender<M>; - drop(chan); - helper_signal::signal(*self.signal.get() as helper_signal::signal); - - // Wait for the child to exit - while !*self.shutdown.get() { - guard = self.cond.wait(guard).unwrap(); - } - drop(guard); - - // Clean up after ourselves - self.lock.destroy(); - helper_signal::close(*self.signal.get() as helper_signal::signal); - *self.signal.get() = 0; - } - } -} diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs index 95294b813ea..b528575bbed 100644 --- a/src/libstd/sys/common/mod.rs +++ b/src/libstd/sys/common/mod.rs @@ -15,7 +15,7 @@ use prelude::v1::*; pub mod backtrace; pub mod condvar; pub mod mutex; -pub mod net2; +pub mod net; pub mod poison; pub mod remutex; pub mod rwlock; diff --git a/src/libstd/sys/common/net2.rs b/src/libstd/sys/common/net.rs index 7da7071670a..7da7071670a 100644 --- a/src/libstd/sys/common/net2.rs +++ b/src/libstd/sys/common/net.rs diff --git a/src/libstd/sys/common/remutex.rs b/src/libstd/sys/common/remutex.rs index 48c74b8d89e..1a467580672 100644 --- a/src/libstd/sys/common/remutex.rs +++ b/src/libstd/sys/common/remutex.rs @@ -19,9 +19,9 @@ use sys::mutex as sys; /// A re-entrant mutual exclusion /// -/// This mutex will block *other* threads waiting for the lock to become available. The thread -/// which has already locked the mutex can lock it multiple times without blocking, preventing a -/// common source of deadlocks. +/// This mutex will block *other* threads waiting for the lock to become +/// available. The thread which has already locked the mutex can lock it +/// multiple times without blocking, preventing a common source of deadlocks. pub struct ReentrantMutex<T> { inner: Box<sys::ReentrantMutex>, poison: poison::Flag, @@ -51,10 +51,14 @@ impl<'a, T> !marker::Send for ReentrantMutexGuard<'a, T> {} impl<T> ReentrantMutex<T> { /// Creates a new reentrant mutex in an unlocked state. pub fn new(t: T) -> ReentrantMutex<T> { - ReentrantMutex { - inner: box unsafe { sys::ReentrantMutex::new() }, - poison: poison::FLAG_INIT, - data: t, + unsafe { + let mut mutex = ReentrantMutex { + inner: box sys::ReentrantMutex::uninitialized(), + poison: poison::FLAG_INIT, + data: t, + }; + mutex.inner.init(); + return mutex } } |
