about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-05-25 20:36:09 -0700
committerbors <bors@rust-lang.org>2016-05-25 20:36:09 -0700
commitd5759a3417fa395d439f4283825504dd4f78dc87 (patch)
treea5ea14cbe5a565002d0e427ea64f54cf4924afe3 /src/libstd/sys
parent267cde2598db3b858730cc1f700f740964343828 (diff)
parentcae91d7c8c21aa860bda29c62207a6726837952b (diff)
downloadrust-d5759a3417fa395d439f4283825504dd4f78dc87.tar.gz
rust-d5759a3417fa395d439f4283825504dd4f78dc87.zip
Auto merge of #33699 - alexcrichton:stabilize-1.10, r=aturon
std: Stabilize APIs for the 1.10 release

This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:

Stabilized:

* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`

Deprecated:

* `StaticCondvar` - this, and all other static synchronization primitives
                    below, are usable today through the lazy-static crate on
                    stable Rust today. Additionally, we'd like the non-static
                    versions to be directly usable in a static context one day,
                    so they're unlikely to be the final forms of the APIs in any
                    case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`

Closes #27717
Closes #27720
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/common/args.rs16
-rw-r--r--src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs28
-rw-r--r--src/libstd/sys/unix/backtrace/tracing/gcc_s.rs36
-rw-r--r--src/libstd/sys/unix/ext/fs.rs4
-rw-r--r--src/libstd/sys/unix/ext/net.rs72
-rw-r--r--src/libstd/sys/unix/fs.rs35
-rw-r--r--src/libstd/sys/unix/os.rs52
-rw-r--r--src/libstd/sys/unix/time.rs318
-rw-r--r--src/libstd/sys/windows/ext/fs.rs19
-rw-r--r--src/libstd/sys/windows/process.rs27
10 files changed, 312 insertions, 295 deletions
diff --git a/src/libstd/sys/common/args.rs b/src/libstd/sys/common/args.rs
index 58417540664..e877391fb8b 100644
--- a/src/libstd/sys/common/args.rs
+++ b/src/libstd/sys/common/args.rs
@@ -48,32 +48,36 @@ mod imp {
     use mem;
     use ffi::CStr;
 
-    use sync::StaticMutex;
+    use sys_common::mutex::Mutex;
 
     static mut GLOBAL_ARGS_PTR: usize = 0;
-    static LOCK: StaticMutex = StaticMutex::new();
+    static LOCK: Mutex = Mutex::new();
 
     pub unsafe fn init(argc: isize, argv: *const *const u8) {
         let args = (0..argc).map(|i| {
             CStr::from_ptr(*argv.offset(i) as *const c_char).to_bytes().to_vec()
         }).collect();
 
-        let _guard = LOCK.lock();
+        LOCK.lock();
         let ptr = get_global_ptr();
         assert!((*ptr).is_none());
         (*ptr) = Some(box args);
+        LOCK.unlock();
     }
 
     pub unsafe fn cleanup() {
-        let _guard = LOCK.lock();
+        LOCK.lock();
         *get_global_ptr() = None;
+        LOCK.unlock();
     }
 
     pub fn clone() -> Option<Vec<Vec<u8>>> {
-        let _guard = LOCK.lock();
         unsafe {
+            LOCK.lock();
             let ptr = get_global_ptr();
-            (*ptr).as_ref().map(|s| (**s).clone())
+            let ret = (*ptr).as_ref().map(|s| (**s).clone());
+            LOCK.unlock();
+            return ret
         }
     }
 
diff --git a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
index de93d3d4e50..ca2e70b5003 100644
--- a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
+++ b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
@@ -18,12 +18,11 @@
 /// simple to use it should be used only on iOS devices as the only viable
 /// option.
 
-use io;
 use io::prelude::*;
+use io;
 use libc;
 use mem;
-use result::Result::Ok;
-use sync::StaticMutex;
+use sys::mutex::Mutex;
 
 use super::super::printing::print;
 
@@ -37,18 +36,21 @@ pub fn write(w: &mut Write) -> io::Result<()> {
     // while it doesn't requires lock for work as everything is
     // local, it still displays much nicer backtraces when a
     // couple of threads panic simultaneously
-    static LOCK: StaticMutex = StaticMutex::new();
-    let _g = LOCK.lock();
+    static LOCK: Mutex = Mutex::new();
+    unsafe {
+        LOCK.lock();
 
-    writeln!(w, "stack backtrace:")?;
-    // 100 lines should be enough
-    const SIZE: usize = 100;
-    let mut buf: [*mut libc::c_void; SIZE] = unsafe { mem::zeroed() };
-    let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as usize};
+        writeln!(w, "stack backtrace:")?;
+        // 100 lines should be enough
+        const SIZE: usize = 100;
+        let mut buf: [*mut libc::c_void; SIZE] = mem::zeroed();
+        let cnt = backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as usize;
 
-    // skipping the first one as it is write itself
-    for i in 1..cnt {
-        print(w, i as isize, buf[i], buf[i])?
+        // skipping the first one as it is write itself
+        for i in 1..cnt {
+            print(w, i as isize, buf[i], buf[i])?
+        }
+        LOCK.unlock();
     }
     Ok(())
 }
diff --git a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
index 5f7ad6918cd..c1b45620ab0 100644
--- a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
+++ b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
@@ -12,7 +12,7 @@ use io;
 use io::prelude::*;
 use libc;
 use mem;
-use sync::StaticMutex;
+use sys_common::mutex::Mutex;
 
 use super::super::printing::print;
 use unwind as uw;
@@ -31,24 +31,28 @@ pub fn write(w: &mut Write) -> io::Result<()> {
     // is semi-reasonable in terms of printing anyway, and we know that all
     // I/O done here is blocking I/O, not green I/O, so we don't have to
     // worry about this being a native vs green mutex.
-    static LOCK: StaticMutex = StaticMutex::new();
-    let _g = LOCK.lock();
+    static LOCK: Mutex = Mutex::new();
+    unsafe {
+        LOCK.lock();
 
-    writeln!(w, "stack backtrace:")?;
+        writeln!(w, "stack backtrace:")?;
 
-    let mut cx = Context { writer: w, last_error: None, idx: 0 };
-    return match unsafe {
-        uw::_Unwind_Backtrace(trace_fn,
-                              &mut cx as *mut Context as *mut libc::c_void)
-    } {
-        uw::_URC_NO_REASON => {
-            match cx.last_error {
-                Some(err) => Err(err),
-                None => Ok(())
+        let mut cx = Context { writer: w, last_error: None, idx: 0 };
+        let ret = match {
+            uw::_Unwind_Backtrace(trace_fn,
+                                  &mut cx as *mut Context as *mut libc::c_void)
+        } {
+            uw::_URC_NO_REASON => {
+                match cx.last_error {
+                    Some(err) => Err(err),
+                    None => Ok(())
+                }
             }
-        }
-        _ => Ok(()),
-    };
+            _ => Ok(()),
+        };
+        LOCK.unlock();
+        return ret
+    }
 
     extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
                        arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index a1528458860..bb90a977433 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -88,9 +88,7 @@ pub trait OpenOptionsExt {
     /// }
     /// let file = options.open("foo.txt");
     /// ```
-    #[unstable(feature = "expand_open_options",
-               reason = "recently added",
-               issue = "30014")]
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn custom_flags(&mut self, flags: i32) -> &mut Self;
 }
 
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index a74f7ea13b4..b5287cce484 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -7,7 +7,8 @@
 // <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.
-#![unstable(feature = "unix_socket", reason = "newly added", issue = "32312")]
+
+#![stable(feature = "unix_socket", since = "1.10.0")]
 
 //! Unix-specific networking functionality
 
@@ -75,6 +76,7 @@ enum AddressKind<'a> {
 
 /// An address associated with a Unix socket.
 #[derive(Clone)]
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct SocketAddr {
     addr: libc::sockaddr_un,
     len: libc::socklen_t,
@@ -109,6 +111,7 @@ impl SocketAddr {
     }
 
     /// Returns true iff the address is unnamed.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn is_unnamed(&self) -> bool {
         if let AddressKind::Unnamed = self.address() {
             true
@@ -118,6 +121,7 @@ impl SocketAddr {
     }
 
     /// Returns the contents of this address if it is a `pathname` address.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn as_pathname(&self) -> Option<&Path> {
         if let AddressKind::Pathname(path) = self.address() {
             Some(path)
@@ -141,6 +145,7 @@ impl SocketAddr {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl fmt::Debug for SocketAddr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match self.address() {
@@ -168,8 +173,6 @@ impl<'a> fmt::Display for AsciiEscaped<'a> {
 /// # Examples
 ///
 /// ```rust,no_run
-/// #![feature(unix_socket)]
-///
 /// use std::os::unix::net::UnixStream;
 /// use std::io::prelude::*;
 ///
@@ -179,8 +182,10 @@ impl<'a> fmt::Display for AsciiEscaped<'a> {
 /// stream.read_to_string(&mut response).unwrap();
 /// println!("{}", response);
 /// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct UnixStream(Socket);
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl fmt::Debug for UnixStream {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let mut builder = fmt.debug_struct("UnixStream");
@@ -197,6 +202,7 @@ impl fmt::Debug for UnixStream {
 
 impl UnixStream {
     /// Connects to the socket named by `path`.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
         fn inner(path: &Path) -> io::Result<UnixStream> {
             unsafe {
@@ -213,6 +219,7 @@ impl UnixStream {
     /// Creates an unnamed pair of connected sockets.
     ///
     /// Returns two `UnixStream`s which are connected to each other.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
         let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
         Ok((UnixStream(i1), UnixStream(i2)))
@@ -224,16 +231,19 @@ impl UnixStream {
     /// object references. Both handles will read and write the same stream of
     /// data, and options set on one stream will be propogated to the other
     /// stream.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixStream> {
         self.0.duplicate().map(UnixStream)
     }
 
     /// Returns the socket address of the local half of this connection.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
     }
 
     /// Returns the socket address of the remote half of this connection.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
     }
@@ -243,6 +253,7 @@ impl UnixStream {
     /// If the provided value is `None`, then `read` calls will block
     /// indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
     }
@@ -252,26 +263,31 @@ impl UnixStream {
     /// If the provided value is `None`, then `write` calls will block
     /// indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
     }
 
     /// Returns the read timeout of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_RCVTIMEO)
     }
 
     /// Returns the write timeout of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_SNDTIMEO)
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
     }
@@ -281,11 +297,13 @@ impl UnixStream {
     /// This function will cause all pending and future I/O calls on the
     /// specified portions to immediately return with an appropriate value
     /// (see the documentation of `Shutdown`).
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         self.0.shutdown(how)
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl io::Read for UnixStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         io::Read::read(&mut &*self, buf)
@@ -296,6 +314,7 @@ impl io::Read for UnixStream {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl<'a> io::Read for &'a UnixStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.read(buf)
@@ -306,6 +325,7 @@ impl<'a> io::Read for &'a UnixStream {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl io::Write for UnixStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         io::Write::write(&mut &*self, buf)
@@ -316,6 +336,7 @@ impl io::Write for UnixStream {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl<'a> io::Write for &'a UnixStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
@@ -326,18 +347,21 @@ impl<'a> io::Write for &'a UnixStream {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl AsRawFd for UnixStream {
     fn as_raw_fd(&self) -> RawFd {
         *self.0.as_inner()
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl FromRawFd for UnixStream {
     unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
         UnixStream(Socket::from_inner(fd))
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl IntoRawFd for UnixStream {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_inner()
@@ -349,8 +373,6 @@ impl IntoRawFd for UnixStream {
 /// # Examples
 ///
 /// ```rust,no_run
-/// #![feature(unix_socket)]
-///
 /// use std::thread;
 /// use std::os::unix::net::{UnixStream, UnixListener};
 ///
@@ -377,8 +399,10 @@ impl IntoRawFd for UnixStream {
 /// // close the listener socket
 /// drop(listener);
 /// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct UnixListener(Socket);
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl fmt::Debug for UnixListener {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let mut builder = fmt.debug_struct("UnixListener");
@@ -392,6 +416,7 @@ impl fmt::Debug for UnixListener {
 
 impl UnixListener {
     /// Creates a new `UnixListener` bound to the specified socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
         fn inner(path: &Path) -> io::Result<UnixListener> {
             unsafe {
@@ -412,6 +437,7 @@ impl UnixListener {
     /// This function will block the calling thread until a new Unix connection
     /// is established. When established, the corersponding `UnixStream` and
     /// the remote peer's address will be returned.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
         let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
         let mut len = mem::size_of_val(&storage) as libc::socklen_t;
@@ -425,21 +451,25 @@ impl UnixListener {
     /// The returned `UnixListener` is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
     /// connections and options set on one listener will affect the other.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixListener> {
         self.0.duplicate().map(UnixListener)
     }
 
     /// Returns the local socket address of this listener.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
     }
@@ -448,29 +478,34 @@ impl UnixListener {
     ///
     /// The iterator will never return `None` and will also not yield the
     /// peer's `SocketAddr` structure.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn incoming<'a>(&'a self) -> Incoming<'a> {
         Incoming { listener: self }
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl AsRawFd for UnixListener {
     fn as_raw_fd(&self) -> RawFd {
         *self.0.as_inner()
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl FromRawFd for UnixListener {
     unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
         UnixListener(Socket::from_inner(fd))
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl IntoRawFd for UnixListener {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_inner()
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl<'a> IntoIterator for &'a UnixListener {
     type Item = io::Result<UnixStream>;
     type IntoIter = Incoming<'a>;
@@ -484,10 +519,12 @@ impl<'a> IntoIterator for &'a UnixListener {
 ///
 /// It will never return `None`.
 #[derive(Debug)]
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct Incoming<'a> {
     listener: &'a UnixListener,
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl<'a> Iterator for Incoming<'a> {
     type Item = io::Result<UnixStream>;
 
@@ -505,8 +542,6 @@ impl<'a> Iterator for Incoming<'a> {
 /// # Examples
 ///
 /// ```rust,no_run
-/// #![feature(unix_socket)]
-///
 /// use std::os::unix::net::UnixDatagram;
 ///
 /// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
@@ -515,8 +550,10 @@ impl<'a> Iterator for Incoming<'a> {
 /// let (count, address) = socket.recv_from(&mut buf).unwrap();
 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
 /// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct UnixDatagram(Socket);
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl fmt::Debug for UnixDatagram {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let mut builder = fmt.debug_struct("UnixDatagram");
@@ -533,6 +570,7 @@ impl fmt::Debug for UnixDatagram {
 
 impl UnixDatagram {
     /// Creates a Unix datagram socket bound to the given path.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
         fn inner(path: &Path) -> io::Result<UnixDatagram> {
             unsafe {
@@ -548,6 +586,7 @@ impl UnixDatagram {
     }
 
     /// Creates a Unix Datagram socket which is not bound to any address.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn unbound() -> io::Result<UnixDatagram> {
         let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
         Ok(UnixDatagram(inner))
@@ -556,6 +595,7 @@ impl UnixDatagram {
     /// Create an unnamed pair of connected sockets.
     ///
     /// Returns two `UnixDatagrams`s which are connected to each other.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
         let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
         Ok((UnixDatagram(i1), UnixDatagram(i2)))
@@ -565,6 +605,7 @@ impl UnixDatagram {
     ///
     /// The `send` method may be used to send data to the specified address.
     /// `recv` and `recv_from` will only receive data from that address.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
         fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
             unsafe {
@@ -583,11 +624,13 @@ impl UnixDatagram {
     /// The returned `UnixListener` is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
     /// connections and options set on one listener will affect the other.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixDatagram> {
         self.0.duplicate().map(UnixDatagram)
     }
 
     /// Returns the address of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
     }
@@ -595,6 +638,7 @@ impl UnixDatagram {
     /// Returns the address of this socket's peer.
     ///
     /// The `connect` method will connect the socket to a peer.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
     }
@@ -603,6 +647,7 @@ impl UnixDatagram {
     ///
     /// On success, returns the number of bytes read and the address from
     /// whence the data came.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
         let mut count = 0;
         let addr = SocketAddr::new(|addr, len| {
@@ -629,6 +674,7 @@ impl UnixDatagram {
     /// Receives data from the socket.
     ///
     /// On success, returns the number of bytes read.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.read(buf)
     }
@@ -636,6 +682,7 @@ impl UnixDatagram {
     /// Sends data on the socket to the specified address.
     ///
     /// On success, returns the number of bytes written.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
         fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
             unsafe {
@@ -659,6 +706,7 @@ impl UnixDatagram {
     /// will return an error if the socket has not already been connected.
     ///
     /// On success, returns the number of bytes written.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
     }
@@ -668,6 +716,7 @@ impl UnixDatagram {
     /// If the provided value is `None`, then `recv` and `recv_from` calls will
     /// block indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
     }
@@ -677,26 +726,31 @@ impl UnixDatagram {
     /// If the provided value is `None`, then `send` and `send_to` calls will
     /// block indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
     }
 
     /// Returns the read timeout of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_RCVTIMEO)
     }
 
     /// Returns the write timeout of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_SNDTIMEO)
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
     }
@@ -706,23 +760,27 @@ impl UnixDatagram {
     /// This function will cause all pending and future I/O calls on the
     /// specified portions to immediately return with an appropriate value
     /// (see the documentation of `Shutdown`).
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         self.0.shutdown(how)
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl AsRawFd for UnixDatagram {
     fn as_raw_fd(&self) -> RawFd {
         *self.0.as_inner()
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl FromRawFd for UnixDatagram {
     unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
         UnixDatagram(Socket::from_inner(fd))
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl IntoRawFd for UnixDatagram {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_inner()
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 0969a59ea43..7f23ae53fcd 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -100,31 +100,6 @@ impl FileAttr {
     }
 }
 
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-// FIXME: update SystemTime to store a timespec and don't lose precision
-impl FileAttr {
-    pub fn modified(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(libc::timeval {
-            tv_sec: self.stat.st_mtime,
-            tv_usec: (self.stat.st_mtime_nsec / 1000) as libc::suseconds_t,
-        }))
-    }
-
-    pub fn accessed(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(libc::timeval {
-            tv_sec: self.stat.st_atime,
-            tv_usec: (self.stat.st_atime_nsec / 1000) as libc::suseconds_t,
-        }))
-    }
-
-    pub fn created(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(libc::timeval {
-            tv_sec: self.stat.st_birthtime,
-            tv_usec: (self.stat.st_birthtime_nsec / 1000) as libc::suseconds_t,
-        }))
-    }
-}
-
 #[cfg(target_os = "netbsd")]
 impl FileAttr {
     pub fn modified(&self) -> io::Result<SystemTime> {
@@ -149,7 +124,7 @@ impl FileAttr {
     }
 }
 
-#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "netbsd")))]
+#[cfg(not(target_os = "netbsd"))]
 impl FileAttr {
     pub fn modified(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
@@ -167,7 +142,9 @@ impl FileAttr {
 
     #[cfg(any(target_os = "bitrig",
               target_os = "freebsd",
-              target_os = "openbsd"))]
+              target_os = "openbsd",
+              target_os = "macos",
+              target_os = "ios"))]
     pub fn created(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
             tv_sec: self.stat.st_birthtime as libc::time_t,
@@ -177,7 +154,9 @@ impl FileAttr {
 
     #[cfg(not(any(target_os = "bitrig",
                   target_os = "freebsd",
-                  target_os = "openbsd")))]
+                  target_os = "openbsd",
+                  target_os = "macos",
+                  target_os = "ios")))]
     pub fn created(&self) -> io::Result<SystemTime> {
         Err(io::Error::new(io::ErrorKind::Other,
                            "creation time is not available on this platform \
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 94ebbd70ae8..21ce6b19ceb 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -27,13 +27,13 @@ use path::{self, PathBuf};
 use ptr;
 use slice;
 use str;
-use sync::StaticMutex;
+use sys_common::mutex::Mutex;
 use sys::cvt;
 use sys::fd;
 use vec;
 
 const TMPBUF_SZ: usize = 128;
-static ENV_LOCK: StaticMutex = StaticMutex::new();
+static ENV_LOCK: Mutex = Mutex::new();
 
 /// Returns the platform-specific value of errno
 #[cfg(not(target_os = "dragonfly"))]
@@ -434,10 +434,11 @@ pub unsafe fn environ() -> *mut *const *const c_char {
 /// Returns a vector of (variable, value) byte-vector pairs for all the
 /// environment variables of the current process.
 pub fn env() -> Env {
-    let _g = ENV_LOCK.lock();
-    return unsafe {
+    unsafe {
+        ENV_LOCK.lock();
         let mut environ = *environ();
         if environ == ptr::null() {
+            ENV_LOCK.unlock();
             panic!("os::env() failure getting env string from OS: {}",
                    io::Error::last_os_error());
         }
@@ -448,8 +449,13 @@ pub fn env() -> Env {
             }
             environ = environ.offset(1);
         }
-        Env { iter: result.into_iter(), _dont_send_or_sync_me: ptr::null_mut() }
-    };
+        let ret = Env {
+            iter: result.into_iter(),
+            _dont_send_or_sync_me: ptr::null_mut(),
+        };
+        ENV_LOCK.unlock();
+        return ret
+    }
 
     fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
         // Strategy (copied from glibc): Variable name and value are separated
@@ -471,32 +477,40 @@ pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
     // environment variables with a nul byte can't be set, so their value is
     // always None as well
     let k = CString::new(k.as_bytes())?;
-    let _g = ENV_LOCK.lock();
-    Ok(unsafe {
+    unsafe {
+        ENV_LOCK.lock();
         let s = libc::getenv(k.as_ptr()) as *const _;
-        if s.is_null() {
+        let ret = if s.is_null() {
             None
         } else {
             Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
-        }
-    })
+        };
+        ENV_LOCK.unlock();
+        return Ok(ret)
+    }
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
     let k = CString::new(k.as_bytes())?;
     let v = CString::new(v.as_bytes())?;
-    let _g = ENV_LOCK.lock();
-    cvt(unsafe {
-        libc::setenv(k.as_ptr(), v.as_ptr(), 1)
-    }).map(|_| ())
+
+    unsafe {
+        ENV_LOCK.lock();
+        let ret = cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ());
+        ENV_LOCK.unlock();
+        return ret
+    }
 }
 
 pub fn unsetenv(n: &OsStr) -> io::Result<()> {
     let nbuf = CString::new(n.as_bytes())?;
-    let _g = ENV_LOCK.lock();
-    cvt(unsafe {
-        libc::unsetenv(nbuf.as_ptr())
-    }).map(|_| ())
+
+    unsafe {
+        ENV_LOCK.lock();
+        let ret = cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ());
+        ENV_LOCK.unlock();
+        return ret
+    }
 }
 
 pub fn page_size() -> usize {
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index cc7abe25e35..68eebba9e7b 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -8,37 +8,129 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use cmp::Ordering;
+use time::Duration;
+use libc;
+
 pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
 
 const NSEC_PER_SEC: u64 = 1_000_000_000;
 
+#[derive(Copy, Clone)]
+struct Timespec {
+    t: libc::timespec,
+}
+
+impl Timespec {
+    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        if self >= other {
+            Ok(if self.t.tv_nsec >= other.t.tv_nsec {
+                Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
+                              (self.t.tv_nsec - other.t.tv_nsec) as u32)
+            } else {
+                Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
+                              self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
+                              other.t.tv_nsec as u32)
+            })
+        } else {
+            match other.sub_timespec(self) {
+                Ok(d) => Err(d),
+                Err(d) => Ok(d),
+            }
+        }
+    }
+
+    fn add_duration(&self, other: &Duration) -> Timespec {
+        let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
+        let mut secs = secs.expect("overflow when adding duration to time");
+
+        // Nano calculations can't overflow because nanos are <1B which fit
+        // in a u32.
+        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
+        if nsec >= NSEC_PER_SEC as u32 {
+            nsec -= NSEC_PER_SEC as u32;
+            secs = secs.checked_add(1).expect("overflow when adding \
+                                               duration to time");
+        }
+        Timespec {
+            t: libc::timespec {
+                tv_sec: secs as libc::time_t,
+                tv_nsec: nsec as libc::c_long,
+            },
+        }
+    }
+
+    fn sub_duration(&self, other: &Duration) -> Timespec {
+        let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
+        let mut secs = secs.expect("overflow when subtracting duration \
+                                    from time");
+
+        // Similar to above, nanos can't overflow.
+        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
+        if nsec < 0 {
+            nsec += NSEC_PER_SEC as i32;
+            secs = secs.checked_sub(1).expect("overflow when subtracting \
+                                               duration from time");
+        }
+        Timespec {
+            t: libc::timespec {
+                tv_sec: secs as libc::time_t,
+                tv_nsec: nsec as libc::c_long,
+            },
+        }
+    }
+}
+
+impl PartialEq for Timespec {
+    fn eq(&self, other: &Timespec) -> bool {
+        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
+    }
+}
+
+impl Eq for Timespec {}
+
+impl PartialOrd for Timespec {
+    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Timespec {
+    fn cmp(&self, other: &Timespec) -> Ordering {
+        let me = (self.t.tv_sec, self.t.tv_nsec);
+        let other = (other.t.tv_sec, other.t.tv_nsec);
+        me.cmp(&other)
+    }
+}
+
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 mod inner {
-    use cmp::Ordering;
     use fmt;
     use libc;
-    use super::NSEC_PER_SEC;
     use sync::Once;
     use sys::cvt;
     use sys_common::mul_div_u64;
     use time::Duration;
 
-    const USEC_PER_SEC: u64 = NSEC_PER_SEC / 1000;
+    use super::NSEC_PER_SEC;
+    use super::Timespec;
 
     #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
     pub struct Instant {
         t: u64
     }
 
-    #[derive(Copy, Clone)]
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct SystemTime {
-        t: libc::timeval,
+        t: Timespec,
     }
 
     pub const UNIX_EPOCH: SystemTime = SystemTime {
-        t: libc::timeval {
-            tv_sec: 0,
-            tv_usec: 0,
+        t: Timespec {
+            t: libc::timespec {
+                tv_sec: 0,
+                tv_nsec: 0,
+            },
         },
     };
 
@@ -72,113 +164,50 @@ mod inner {
 
     impl SystemTime {
         pub fn now() -> SystemTime {
-            let mut s = SystemTime {
-                t: libc::timeval {
-                    tv_sec: 0,
-                    tv_usec: 0,
-                },
+            let mut s = libc::timeval {
+                tv_sec: 0,
+                tv_usec: 0,
             };
             cvt(unsafe {
-                libc::gettimeofday(&mut s.t, 0 as *mut _)
+                libc::gettimeofday(&mut s, 0 as *mut _)
             }).unwrap();
-            return s
+            return SystemTime::from(s)
         }
 
         pub fn sub_time(&self, other: &SystemTime)
                         -> Result<Duration, Duration> {
-            if self >= other {
-                Ok(if self.t.tv_usec >= other.t.tv_usec {
-                    Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
-                                  ((self.t.tv_usec -
-                                    other.t.tv_usec) as u32) * 1000)
-                } else {
-                    Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
-                                  (self.t.tv_usec as u32 + (USEC_PER_SEC as u32) -
-                                   other.t.tv_usec as u32) * 1000)
-                })
-            } else {
-                match other.sub_time(self) {
-                    Ok(d) => Err(d),
-                    Err(d) => Ok(d),
-                }
-            }
+            self.t.sub_timespec(&other.t)
         }
 
         pub fn add_duration(&self, other: &Duration) -> SystemTime {
-            let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
-            let mut secs = secs.expect("overflow when adding duration to time");
-
-            // Nano calculations can't overflow because nanos are <1B which fit
-            // in a u32.
-            let mut usec = (other.subsec_nanos() / 1000) + self.t.tv_usec as u32;
-            if usec >= USEC_PER_SEC as u32 {
-                usec -= USEC_PER_SEC as u32;
-                secs = secs.checked_add(1).expect("overflow when adding \
-                                                   duration to time");
-            }
-            SystemTime {
-                t: libc::timeval {
-                    tv_sec: secs as libc::time_t,
-                    tv_usec: usec as libc::suseconds_t,
-                },
-            }
+            SystemTime { t: self.t.add_duration(other) }
         }
 
         pub fn sub_duration(&self, other: &Duration) -> SystemTime {
-            let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
-            let mut secs = secs.expect("overflow when subtracting duration \
-                                        from time");
-
-            // Similar to above, nanos can't overflow.
-            let mut usec = self.t.tv_usec as i32 -
-                           (other.subsec_nanos() / 1000) as i32;
-            if usec < 0 {
-                usec += USEC_PER_SEC as i32;
-                secs = secs.checked_sub(1).expect("overflow when subtracting \
-                                                   duration from time");
-            }
-            SystemTime {
-                t: libc::timeval {
-                    tv_sec: secs as libc::time_t,
-                    tv_usec: usec as libc::suseconds_t,
-                },
-            }
+            SystemTime { t: self.t.sub_duration(other) }
         }
     }
 
     impl From<libc::timeval> for SystemTime {
         fn from(t: libc::timeval) -> SystemTime {
-            SystemTime { t: t }
-        }
-    }
-
-    impl PartialEq for SystemTime {
-        fn eq(&self, other: &SystemTime) -> bool {
-            self.t.tv_sec == other.t.tv_sec && self.t.tv_usec == other.t.tv_usec
-        }
-    }
-
-    impl Eq for SystemTime {}
-
-    impl PartialOrd for SystemTime {
-        fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> {
-            Some(self.cmp(other))
+            SystemTime::from(libc::timespec {
+                tv_sec: t.tv_sec,
+                tv_nsec: (t.tv_usec * 1000) as libc::c_long,
+            })
         }
     }
 
-    impl Ord for SystemTime {
-        fn cmp(&self, other: &SystemTime) -> Ordering {
-            let me = (self.t.tv_sec, self.t.tv_usec);
-            let other = (other.t.tv_sec, other.t.tv_usec);
-            me.cmp(&other)
+    impl From<libc::timespec> for SystemTime {
+        fn from(t: libc::timespec) -> SystemTime {
+            SystemTime { t: Timespec { t: t } }
         }
     }
 
     impl fmt::Debug for SystemTime {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             f.debug_struct("SystemTime")
-             .field("tv_sec", &self.t.tv_sec)
-             .field("tv_usec", &self.t.tv_usec)
+             .field("tv_sec", &self.t.t.tv_sec)
+             .field("tv_nsec", &self.t.t.tv_nsec)
              .finish()
         }
     }
@@ -209,17 +238,12 @@ mod inner {
 
 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
 mod inner {
-    use cmp::Ordering;
     use fmt;
     use libc;
-    use super::NSEC_PER_SEC;
     use sys::cvt;
     use time::Duration;
 
-    #[derive(Copy, Clone)]
-    struct Timespec {
-        t: libc::timespec,
-    }
+    use super::Timespec;
 
     #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct Instant {
@@ -242,7 +266,7 @@ mod inner {
 
     impl Instant {
         pub fn now() -> Instant {
-            Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) }
+            Instant { t: now(libc::CLOCK_MONOTONIC) }
         }
 
         pub fn sub_instant(&self, other: &Instant) -> Duration {
@@ -271,7 +295,7 @@ mod inner {
 
     impl SystemTime {
         pub fn now() -> SystemTime {
-            SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
+            SystemTime { t: now(libc::CLOCK_REALTIME) }
         }
 
         pub fn sub_time(&self, other: &SystemTime)
@@ -308,98 +332,16 @@ mod inner {
     #[cfg(target_os = "dragonfly")]
     pub type clock_t = libc::c_ulong;
 
-    impl Timespec {
-        pub fn now(clock: clock_t) -> Timespec {
-            let mut t = Timespec {
-                t: libc::timespec {
-                    tv_sec: 0,
-                    tv_nsec: 0,
-                }
-            };
-            cvt(unsafe {
-                libc::clock_gettime(clock, &mut t.t)
-            }).unwrap();
-            t
-        }
-
-        fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-            if self >= other {
-                Ok(if self.t.tv_nsec >= other.t.tv_nsec {
-                    Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
-                                  (self.t.tv_nsec - other.t.tv_nsec) as u32)
-                } else {
-                    Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
-                                  self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
-                                  other.t.tv_nsec as u32)
-                })
-            } else {
-                match other.sub_timespec(self) {
-                    Ok(d) => Err(d),
-                    Err(d) => Ok(d),
-                }
-            }
-        }
-
-        fn add_duration(&self, other: &Duration) -> Timespec {
-            let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
-            let mut secs = secs.expect("overflow when adding duration to time");
-
-            // Nano calculations can't overflow because nanos are <1B which fit
-            // in a u32.
-            let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
-            if nsec >= NSEC_PER_SEC as u32 {
-                nsec -= NSEC_PER_SEC as u32;
-                secs = secs.checked_add(1).expect("overflow when adding \
-                                                   duration to time");
-            }
-            Timespec {
-                t: libc::timespec {
-                    tv_sec: secs as libc::time_t,
-                    tv_nsec: nsec as libc::c_long,
-                },
-            }
-        }
-
-        fn sub_duration(&self, other: &Duration) -> Timespec {
-            let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
-            let mut secs = secs.expect("overflow when subtracting duration \
-                                        from time");
-
-            // Similar to above, nanos can't overflow.
-            let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
-            if nsec < 0 {
-                nsec += NSEC_PER_SEC as i32;
-                secs = secs.checked_sub(1).expect("overflow when subtracting \
-                                                   duration from time");
-            }
-            Timespec {
-                t: libc::timespec {
-                    tv_sec: secs as libc::time_t,
-                    tv_nsec: nsec as libc::c_long,
-                },
+    fn now(clock: clock_t) -> Timespec {
+        let mut t = Timespec {
+            t: libc::timespec {
+                tv_sec: 0,
+                tv_nsec: 0,
             }
-        }
-    }
-
-    impl PartialEq for Timespec {
-        fn eq(&self, other: &Timespec) -> bool {
-            self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
-        }
-    }
-
-    impl Eq for Timespec {}
-
-    impl PartialOrd for Timespec {
-        fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
-            Some(self.cmp(other))
-        }
-    }
-
-    impl Ord for Timespec {
-        fn cmp(&self, other: &Timespec) -> Ordering {
-            let me = (self.t.tv_sec, self.t.tv_nsec);
-            let other = (other.t.tv_sec, other.t.tv_nsec);
-            me.cmp(&other)
-        }
+        };
+        cvt(unsafe {
+            libc::clock_gettime(clock, &mut t.t)
+        }).unwrap();
+        t
     }
 }
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index d378a6853f3..4388a0bdff2 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -19,9 +19,7 @@ use sys;
 use sys_common::{AsInnerMut, AsInner};
 
 /// Windows-specific extensions to `OpenOptions`
-#[unstable(feature = "open_options_ext",
-           reason = "may require more thought/methods",
-           issue = "27720")]
+#[stable(feature = "open_options_ext", since = "1.10.0")]
 pub trait OpenOptionsExt {
     /// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
     /// with the specified value.
@@ -34,7 +32,6 @@ pub trait OpenOptionsExt {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(open_options_ext)]
     /// use std::fs::OpenOptions;
     /// use std::os::windows::fs::OpenOptionsExt;
     ///
@@ -42,6 +39,7 @@ pub trait OpenOptionsExt {
     /// // to call `stat()` on the file
     /// let file = OpenOptions::new().access_mode(0).open("foo.txt");
     /// ```
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn access_mode(&mut self, access: u32) -> &mut Self;
 
     /// Overrides the `dwShareMode` argument to the call to `CreateFile` with
@@ -55,7 +53,6 @@ pub trait OpenOptionsExt {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(open_options_ext)]
     /// use std::fs::OpenOptions;
     /// use std::os::windows::fs::OpenOptionsExt;
     ///
@@ -65,6 +62,7 @@ pub trait OpenOptionsExt {
     ///                              .share_mode(0)
     ///                              .open("foo.txt");
     /// ```
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn share_mode(&mut self, val: u32) -> &mut Self;
 
     /// Sets extra flags for the `dwFileFlags` argument to the call to
@@ -88,9 +86,7 @@ pub trait OpenOptionsExt {
     /// }
     /// let file = options.open("foo.txt");
     /// ```
-    #[unstable(feature = "expand_open_options",
-               reason = "recently added",
-               issue = "30014")]
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn custom_flags(&mut self, flags: u32) -> &mut Self;
 
     /// Sets the `dwFileAttributes` argument to the call to `CreateFile2` to
@@ -111,7 +107,6 @@ pub trait OpenOptionsExt {
     /// # Examples
     ///
     /// ```rust,ignore
-    /// #![feature(open_options_ext)]
     /// extern crate winapi;
     /// use std::fs::OpenOptions;
     /// use std::os::windows::fs::OpenOptionsExt;
@@ -120,17 +115,17 @@ pub trait OpenOptionsExt {
     ///                              .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
     ///                              .open("foo.txt");
     /// ```
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn attributes(&mut self, val: u32) -> &mut Self;
 
     /// Sets the `dwSecurityQosFlags` argument to the call to `CreateFile2` to
     /// the specified value (or combines it with `custom_flags` and `attributes`
     /// to set the `dwFlagsAndAttributes` for `CreateFile`).
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions;
 }
 
-#[unstable(feature = "open_options_ext",
-           reason = "may require more thought/methods",
-           issue = "27720")]
+#[stable(feature = "open_options_ext", since = "1.10.0")]
 impl OpenOptionsExt for OpenOptions {
     fn access_mode(&mut self, access: u32) -> &mut OpenOptions {
         self.as_inner_mut().access_mode(access); self
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index a0ad866c69d..3ca75cf3643 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -24,7 +24,7 @@ use mem;
 use os::windows::ffi::OsStrExt;
 use path::Path;
 use ptr;
-use sync::StaticMutex;
+use sys::mutex::Mutex;
 use sys::c;
 use sys::fs::{OpenOptions, File};
 use sys::handle::Handle;
@@ -75,6 +75,10 @@ pub struct StdioPipes {
     pub stderr: Option<AnonPipe>,
 }
 
+struct DropGuard<'a> {
+    lock: &'a Mutex,
+}
+
 impl Command {
     pub fn new(program: &OsStr) -> Command {
         Command {
@@ -173,8 +177,8 @@ impl Command {
         //
         // For more information, msdn also has an article about this race:
         // http://support.microsoft.com/kb/315939
-        static CREATE_PROCESS_LOCK: StaticMutex = StaticMutex::new();
-        let _lock = CREATE_PROCESS_LOCK.lock();
+        static CREATE_PROCESS_LOCK: Mutex = Mutex::new();
+        let _guard = DropGuard::new(&CREATE_PROCESS_LOCK);
 
         let mut pipes = StdioPipes {
             stdin: None,
@@ -224,6 +228,23 @@ impl fmt::Debug for Command {
     }
 }
 
+impl<'a> DropGuard<'a> {
+    fn new(lock: &'a Mutex) -> DropGuard<'a> {
+        unsafe {
+            lock.lock();
+            DropGuard { lock: lock }
+        }
+    }
+}
+
+impl<'a> Drop for DropGuard<'a> {
+    fn drop(&mut self) {
+        unsafe {
+            self.lock.unlock();
+        }
+    }
+}
+
 impl Stdio {
     fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>)
                  -> io::Result<Handle> {