about summary refs log tree commit diff
path: root/src/libstd/sys/common
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-05-12 12:48:14 +1200
committerNick Cameron <ncameron@mozilla.com>2015-05-12 12:48:14 +1200
commite0216fcc42d5f4961d07378a783c87814097015f (patch)
treee5f503c129942a2b7c2815b1c8e4db85b5bbcf1b /src/libstd/sys/common
parentaa5ca282b20391c6df51fdfa94e0de5672ccfac1 (diff)
parent750f2c63f2737305d33288303cdecb7a470a7922 (diff)
downloadrust-e0216fcc42d5f4961d07378a783c87814097015f.tar.gz
rust-e0216fcc42d5f4961d07378a783c87814097015f.zip
Merge branch 'master' into
Diffstat (limited to 'src/libstd/sys/common')
-rw-r--r--src/libstd/sys/common/helper_thread.rs170
-rw-r--r--src/libstd/sys/common/mod.rs2
-rw-r--r--src/libstd/sys/common/net.rs (renamed from src/libstd/sys/common/net2.rs)47
-rw-r--r--src/libstd/sys/common/poison.rs11
-rw-r--r--src/libstd/sys/common/remutex.rs18
-rw-r--r--src/libstd/sys/common/stack.rs4
-rw-r--r--src/libstd/sys/common/wtf8.rs8
7 files changed, 71 insertions, 189 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 2b2c31d92ed..7da7071670a 100644
--- a/src/libstd/sys/common/net2.rs
+++ b/src/libstd/sys/common/net.rs
@@ -11,6 +11,7 @@
 use prelude::v1::*;
 
 use ffi::{CStr, CString};
+use fmt;
 use io::{self, Error, ErrorKind};
 use libc::{self, c_int, c_char, c_void, socklen_t};
 use mem;
@@ -268,6 +269,24 @@ impl FromInner<Socket> for TcpStream {
     }
 }
 
+impl fmt::Debug for TcpStream {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut res = f.debug_struct("TcpStream");
+
+        if let Ok(addr) = self.socket_addr() {
+            res = res.field("addr", &addr);
+        }
+
+        if let Ok(peer) = self.peer_addr() {
+            res = res.field("peer", &peer);
+        }
+
+        let name = if cfg!(windows) {"socket"} else {"fd"};
+        res = res.field(name, &self.inner.as_inner());
+        res.finish()
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // TCP listeners
 ////////////////////////////////////////////////////////////////////////////////
@@ -327,6 +346,20 @@ impl FromInner<Socket> for TcpListener {
     }
 }
 
+impl fmt::Debug for TcpListener {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut res = f.debug_struct("TcpListener");
+
+        if let Ok(addr) = self.socket_addr() {
+            res = res.field("addr", &addr);
+        }
+
+        let name = if cfg!(windows) {"socket"} else {"fd"};
+        res = res.field(name, &self.inner.as_inner());
+        res.finish()
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // UDP
 ////////////////////////////////////////////////////////////////////////////////
@@ -445,3 +478,17 @@ impl FromInner<Socket> for UdpSocket {
         UdpSocket { inner: socket }
     }
 }
+
+impl fmt::Debug for UdpSocket {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut res = f.debug_struct("UdpSocket");
+
+        if let Ok(addr) = self.socket_addr() {
+            res = res.field("addr", &addr);
+        }
+
+        let name = if cfg!(windows) {"socket"} else {"fd"};
+        res = res.field(name, &self.inner.as_inner());
+        res.finish()
+    }
+}
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs
index 6deb4a48007..67679c11a98 100644
--- a/src/libstd/sys/common/poison.rs
+++ b/src/libstd/sys/common/poison.rs
@@ -10,6 +10,7 @@
 
 use prelude::v1::*;
 
+use marker::Reflect;
 use cell::UnsafeCell;
 use error::{Error};
 use fmt;
@@ -54,7 +55,7 @@ pub struct Guard {
 
 /// A type of error which can be returned whenever a lock is acquired.
 ///
-/// Both Mutexes and RwLocks are poisoned whenever a task fails while the lock
+/// Both Mutexes and RwLocks are poisoned whenever a thread fails while the lock
 /// is held. The precise semantics for when a lock is poisoned is documented on
 /// each lock, but once a lock is poisoned then all future acquisitions will
 /// return this error.
@@ -67,7 +68,7 @@ pub struct PoisonError<T> {
 /// `try_lock` method.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum TryLockError<T> {
-    /// The lock could not be acquired because another task failed while holding
+    /// The lock could not be acquired because another thread failed while holding
     /// the lock.
     #[stable(feature = "rust1", since = "1.0.0")]
     Poisoned(PoisonError<T>),
@@ -109,7 +110,7 @@ impl<T> fmt::Display for PoisonError<T> {
     }
 }
 
-impl<T: Send> Error for PoisonError<T> {
+impl<T: Send + Reflect> Error for PoisonError<T> {
     fn description(&self) -> &str {
         "poisoned lock: another task failed inside"
     }
@@ -155,13 +156,13 @@ impl<T> fmt::Debug for TryLockError<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> fmt::Display for TryLockError<T> {
+impl<T: Send + Reflect> fmt::Display for TryLockError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.description().fmt(f)
     }
 }
 
-impl<T: Send> Error for TryLockError<T> {
+impl<T: Send + Reflect> Error for TryLockError<T> {
     fn description(&self) -> &str {
         match *self {
             TryLockError::Poisoned(ref p) => p.description(),
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
         }
     }
 
diff --git a/src/libstd/sys/common/stack.rs b/src/libstd/sys/common/stack.rs
index 8dc3407db77..fadeebc8150 100644
--- a/src/libstd/sys/common/stack.rs
+++ b/src/libstd/sys/common/stack.rs
@@ -11,13 +11,13 @@
 //! Rust stack-limit management
 //!
 //! Currently Rust uses a segmented-stack-like scheme in order to detect stack
-//! overflow for rust tasks. In this scheme, the prologue of all functions are
+//! overflow for rust threads. In this scheme, the prologue of all functions are
 //! preceded with a check to see whether the current stack limits are being
 //! exceeded.
 //!
 //! This module provides the functionality necessary in order to manage these
 //! stack limits (which are stored in platform-specific locations). The
-//! functions here are used at the borders of the task lifetime in order to
+//! functions here are used at the borders of the thread lifetime in order to
 //! manage these limits.
 //!
 //! This function is an unstable module because this scheme for stack overflow
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index 56a952e6a7e..cb9239ed7ba 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -161,7 +161,7 @@ impl Wtf8Buf {
         Wtf8Buf { bytes: Vec::with_capacity(n) }
     }
 
-    /// Creates a WTF-8 string from an UTF-8 `String`.
+    /// Creates a WTF-8 string from a UTF-8 `String`.
     ///
     /// This takes ownership of the `String` and does not copy.
     ///
@@ -171,7 +171,7 @@ impl Wtf8Buf {
         Wtf8Buf { bytes: string.into_bytes() }
     }
 
-    /// Creates a WTF-8 string from an UTF-8 `&str` slice.
+    /// Creates a WTF-8 string from a UTF-8 `&str` slice.
     ///
     /// This copies the content of the slice.
     ///
@@ -245,7 +245,7 @@ impl Wtf8Buf {
         self.bytes.capacity()
     }
 
-    /// Append an UTF-8 slice at the end of the string.
+    /// Append a UTF-8 slice at the end of the string.
     #[inline]
     pub fn push_str(&mut self, other: &str) {
         self.bytes.push_all(other.as_bytes())
@@ -527,7 +527,7 @@ impl Wtf8 {
     }
 
     /// Lossily converts the string to UTF-8.
-    /// Returns an UTF-8 `&str` slice if the contents are well-formed in UTF-8.
+    /// Returns a UTF-8 `&str` slice if the contents are well-formed in UTF-8.
     ///
     /// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”).
     ///