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
This commit is contained in:
commit
d5759a3417
37 changed files with 567 additions and 494 deletions
|
@ -592,6 +592,31 @@ impl<T: ?Sized> Drop for Arc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Weak<T> {
|
||||||
|
/// Constructs a new `Weak<T>` without an accompanying instance of T.
|
||||||
|
///
|
||||||
|
/// This allocates memory for T, but does not initialize it. Calling
|
||||||
|
/// Weak<T>::upgrade() on the return value always gives None.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::sync::Weak;
|
||||||
|
///
|
||||||
|
/// let empty: Weak<i64> = Weak::new();
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||||
|
pub fn new() -> Weak<T> {
|
||||||
|
unsafe {
|
||||||
|
Weak { ptr: Shared::new(Box::into_raw(box ArcInner {
|
||||||
|
strong: atomic::AtomicUsize::new(0),
|
||||||
|
weak: atomic::AtomicUsize::new(1),
|
||||||
|
data: uninitialized(),
|
||||||
|
}))}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> Weak<T> {
|
impl<T: ?Sized> Weak<T> {
|
||||||
/// Upgrades a weak reference to a strong reference.
|
/// Upgrades a weak reference to a strong reference.
|
||||||
///
|
///
|
||||||
|
@ -682,6 +707,13 @@ impl<T: ?Sized> Clone for Weak<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||||
|
impl<T> Default for Weak<T> {
|
||||||
|
fn default() -> Weak<T> {
|
||||||
|
Weak::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "arc_weak", since = "1.4.0")]
|
#[stable(feature = "arc_weak", since = "1.4.0")]
|
||||||
impl<T: ?Sized> Drop for Weak<T> {
|
impl<T: ?Sized> Drop for Weak<T> {
|
||||||
/// Drops the `Weak<T>`.
|
/// Drops the `Weak<T>`.
|
||||||
|
@ -907,35 +939,6 @@ impl<T> From<T> for Arc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Weak<T> {
|
|
||||||
/// Constructs a new `Weak<T>` without an accompanying instance of T.
|
|
||||||
///
|
|
||||||
/// This allocates memory for T, but does not initialize it. Calling
|
|
||||||
/// Weak<T>::upgrade() on the return value always gives None.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(downgraded_weak)]
|
|
||||||
///
|
|
||||||
/// use std::sync::Weak;
|
|
||||||
///
|
|
||||||
/// let empty: Weak<i64> = Weak::new();
|
|
||||||
/// ```
|
|
||||||
#[unstable(feature = "downgraded_weak",
|
|
||||||
reason = "recently added",
|
|
||||||
issue = "30425")]
|
|
||||||
pub fn new() -> Weak<T> {
|
|
||||||
unsafe {
|
|
||||||
Weak { ptr: Shared::new(Box::into_raw(box ArcInner {
|
|
||||||
strong: atomic::AtomicUsize::new(0),
|
|
||||||
weak: atomic::AtomicUsize::new(1),
|
|
||||||
data: uninitialized(),
|
|
||||||
}))}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
|
|
|
@ -90,7 +90,6 @@
|
||||||
#![feature(unique)]
|
#![feature(unique)]
|
||||||
#![feature(unsafe_no_drop_flag, filling_drop)]
|
#![feature(unsafe_no_drop_flag, filling_drop)]
|
||||||
#![feature(unsize)]
|
#![feature(unsize)]
|
||||||
#![feature(extended_compare_and_swap)]
|
|
||||||
|
|
||||||
#![cfg_attr(not(test), feature(raw, fn_traits, placement_new_protocol))]
|
#![cfg_attr(not(test), feature(raw, fn_traits, placement_new_protocol))]
|
||||||
#![cfg_attr(test, feature(test, box_heap))]
|
#![cfg_attr(test, feature(test, box_heap))]
|
||||||
|
|
|
@ -720,6 +720,33 @@ impl<T: ?Sized> !marker::Sync for Weak<T> {}
|
||||||
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
||||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
|
||||||
|
|
||||||
|
impl<T> Weak<T> {
|
||||||
|
/// Constructs a new `Weak<T>` without an accompanying instance of T.
|
||||||
|
///
|
||||||
|
/// This allocates memory for T, but does not initialize it. Calling
|
||||||
|
/// Weak<T>::upgrade() on the return value always gives None.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Weak;
|
||||||
|
///
|
||||||
|
/// let empty: Weak<i64> = Weak::new();
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||||
|
pub fn new() -> Weak<T> {
|
||||||
|
unsafe {
|
||||||
|
Weak {
|
||||||
|
ptr: Shared::new(Box::into_raw(box RcBox {
|
||||||
|
strong: Cell::new(0),
|
||||||
|
weak: Cell::new(1),
|
||||||
|
value: uninitialized(),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> Weak<T> {
|
impl<T: ?Sized> Weak<T> {
|
||||||
/// Upgrades a weak reference to a strong reference.
|
/// Upgrades a weak reference to a strong reference.
|
||||||
///
|
///
|
||||||
|
@ -823,34 +850,10 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Weak<T> {
|
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||||
/// Constructs a new `Weak<T>` without an accompanying instance of T.
|
impl<T> Default for Weak<T> {
|
||||||
///
|
fn default() -> Weak<T> {
|
||||||
/// This allocates memory for T, but does not initialize it. Calling
|
Weak::new()
|
||||||
/// Weak<T>::upgrade() on the return value always gives None.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(downgraded_weak)]
|
|
||||||
///
|
|
||||||
/// use std::rc::Weak;
|
|
||||||
///
|
|
||||||
/// let empty: Weak<i64> = Weak::new();
|
|
||||||
/// ```
|
|
||||||
#[unstable(feature = "downgraded_weak",
|
|
||||||
reason = "recently added",
|
|
||||||
issue="30425")]
|
|
||||||
pub fn new() -> Weak<T> {
|
|
||||||
unsafe {
|
|
||||||
Weak {
|
|
||||||
ptr: Shared::new(Box::into_raw(box RcBox {
|
|
||||||
strong: Cell::new(0),
|
|
||||||
weak: Cell::new(1),
|
|
||||||
value: uninitialized(),
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ pub struct Values<'a, K: 'a, V: 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutable iterator over a BTreeMap's values.
|
/// A mutable iterator over a BTreeMap's values.
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
pub struct ValuesMut<'a, K: 'a, V: 'a> {
|
pub struct ValuesMut<'a, K: 'a, V: 'a> {
|
||||||
inner: IterMut<'a, K, V>,
|
inner: IterMut<'a, K, V>,
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1144,7 @@ impl<'a, K, V> Iterator for Range<'a, K, V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
|
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
|
||||||
type Item = &'a mut V;
|
type Item = &'a mut V;
|
||||||
|
|
||||||
|
@ -1157,14 +1157,14 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
impl<'a, K, V> DoubleEndedIterator for ValuesMut<'a, K, V> {
|
impl<'a, K, V> DoubleEndedIterator for ValuesMut<'a, K, V> {
|
||||||
fn next_back(&mut self) -> Option<&'a mut V> {
|
fn next_back(&mut self) -> Option<&'a mut V> {
|
||||||
self.inner.next_back().map(|(_, v)| v)
|
self.inner.next_back().map(|(_, v)| v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
|
impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.inner.len()
|
self.inner.len()
|
||||||
|
@ -1575,7 +1575,6 @@ impl<K, V> BTreeMap<K, V> {
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(map_values_mut)]
|
|
||||||
/// use std::collections::BTreeMap;
|
/// use std::collections::BTreeMap;
|
||||||
///
|
///
|
||||||
/// let mut a = BTreeMap::new();
|
/// let mut a = BTreeMap::new();
|
||||||
|
@ -1590,8 +1589,8 @@ impl<K, V> BTreeMap<K, V> {
|
||||||
/// assert_eq!(values, [String::from("hello!"),
|
/// assert_eq!(values, [String::from("hello!"),
|
||||||
/// String::from("goodbye!")]);
|
/// String::from("goodbye!")]);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
pub fn values_mut<'a>(&'a mut self) -> ValuesMut<'a, K, V> {
|
pub fn values_mut(&mut self) -> ValuesMut<K, V> {
|
||||||
ValuesMut { inner: self.iter_mut() }
|
ValuesMut { inner: self.iter_mut() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1656,7 +1655,7 @@ impl<'a, K: Ord, V> Entry<'a, K, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to this entry's key.
|
/// Returns a reference to this entry's key.
|
||||||
#[unstable(feature = "map_entry_keys", issue = "32281")]
|
#[stable(feature = "map_entry_keys", since = "1.10.0")]
|
||||||
pub fn key(&self) -> &K {
|
pub fn key(&self) -> &K {
|
||||||
match *self {
|
match *self {
|
||||||
Occupied(ref entry) => entry.key(),
|
Occupied(ref entry) => entry.key(),
|
||||||
|
@ -1668,7 +1667,7 @@ impl<'a, K: Ord, V> Entry<'a, K, V> {
|
||||||
impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
|
impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
|
||||||
/// Gets a reference to the key that would be used when inserting a value
|
/// Gets a reference to the key that would be used when inserting a value
|
||||||
/// through the VacantEntry.
|
/// through the VacantEntry.
|
||||||
#[unstable(feature = "map_entry_keys", issue = "32281")]
|
#[stable(feature = "map_entry_keys", since = "1.10.0")]
|
||||||
pub fn key(&self) -> &K {
|
pub fn key(&self) -> &K {
|
||||||
&self.key
|
&self.key
|
||||||
}
|
}
|
||||||
|
@ -1718,7 +1717,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
|
||||||
|
|
||||||
impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
|
impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
|
||||||
/// Gets a reference to the key in the entry.
|
/// Gets a reference to the key in the entry.
|
||||||
#[unstable(feature = "map_entry_keys", issue = "32281")]
|
#[stable(feature = "map_entry_keys", since = "1.10.0")]
|
||||||
pub fn key(&self) -> &K {
|
pub fn key(&self) -> &K {
|
||||||
self.handle.reborrow().into_kv().0
|
self.handle.reborrow().into_kv().0
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
|
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
|
||||||
|
|
||||||
#![cfg_attr(test, allow(deprecated))] // rand
|
#![cfg_attr(test, allow(deprecated))] // rand
|
||||||
#![cfg_attr(not(test), feature(slice_binary_search_by_key))] // impl [T]
|
|
||||||
#![cfg_attr(not(stage0), deny(warnings))]
|
#![cfg_attr(not(stage0), deny(warnings))]
|
||||||
|
|
||||||
#![feature(alloc)]
|
#![feature(alloc)]
|
||||||
|
|
|
@ -759,7 +759,6 @@ impl<T> [T] {
|
||||||
/// fourth could match any position in `[1,4]`.
|
/// fourth could match any position in `[1,4]`.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(slice_binary_search_by_key)]
|
|
||||||
/// let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
|
/// let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
|
||||||
/// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
|
/// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
|
||||||
/// (1, 21), (2, 34), (4, 55)];
|
/// (1, 21), (2, 34), (4, 55)];
|
||||||
|
@ -770,7 +769,7 @@ impl<T> [T] {
|
||||||
/// let r = s.binary_search_by_key(&1, |&(a,b)| b);
|
/// let r = s.binary_search_by_key(&1, |&(a,b)| b);
|
||||||
/// assert!(match r { Ok(1...4) => true, _ => false, });
|
/// assert!(match r { Ok(1...4) => true, _ => false, });
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "slice_binary_search_by_key", reason = "recently added", issue = "33018")]
|
#[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn binary_search_by_key<B, F>(&self, b: &B, f: F) -> Result<usize, usize>
|
pub fn binary_search_by_key<B, F>(&self, b: &B, f: F) -> Result<usize, usize>
|
||||||
where F: FnMut(&T) -> B,
|
where F: FnMut(&T) -> B,
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
#![feature(enumset)]
|
#![feature(enumset)]
|
||||||
#![feature(iter_arith)]
|
#![feature(iter_arith)]
|
||||||
#![feature(linked_list_contains)]
|
#![feature(linked_list_contains)]
|
||||||
#![feature(map_entry_keys)]
|
|
||||||
#![feature(map_values_mut)]
|
|
||||||
#![feature(pattern)]
|
#![feature(pattern)]
|
||||||
#![feature(rand)]
|
#![feature(rand)]
|
||||||
#![feature(step_by)]
|
#![feature(step_by)]
|
||||||
|
|
|
@ -15,11 +15,9 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
#![stable(feature = "core_char", since = "1.2.0")]
|
#![stable(feature = "core_char", since = "1.2.0")]
|
||||||
|
|
||||||
use iter::Iterator;
|
use prelude::v1::*;
|
||||||
|
|
||||||
use mem::transmute;
|
use mem::transmute;
|
||||||
use option::Option::{None, Some};
|
|
||||||
use option::Option;
|
|
||||||
use slice::SliceExt;
|
|
||||||
|
|
||||||
// UTF-8 ranges and tags for encoding characters
|
// UTF-8 ranges and tags for encoding characters
|
||||||
const TAG_CONT: u8 = 0b1000_0000;
|
const TAG_CONT: u8 = 0b1000_0000;
|
||||||
|
|
|
@ -1125,6 +1125,7 @@ impl<I: Iterator> Peekable<I> {
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "peekable_is_empty", issue = "32111")]
|
#[unstable(feature = "peekable_is_empty", issue = "32111")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[rustc_deprecated(since = "1.10.0", reason = "replaced by .peek().is_none()")]
|
||||||
pub fn is_empty(&mut self) -> bool {
|
pub fn is_empty(&mut self) -> bool {
|
||||||
self.peek().is_none()
|
self.peek().is_none()
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,10 @@ pub trait SliceExt {
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
|
fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
|
||||||
where F: FnMut(&Self::Item) -> Ordering;
|
where F: FnMut(&Self::Item) -> Ordering;
|
||||||
|
#[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
|
||||||
|
fn binary_search_by_key<B, F>(&self, b: &B, f: F) -> Result<usize, usize>
|
||||||
|
where F: FnMut(&Self::Item) -> B,
|
||||||
|
B: Ord;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
|
@ -157,11 +161,6 @@ pub trait SliceExt {
|
||||||
fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
|
fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
|
||||||
#[stable(feature = "copy_from_slice", since = "1.9.0")]
|
#[stable(feature = "copy_from_slice", since = "1.9.0")]
|
||||||
fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
|
fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
|
||||||
|
|
||||||
#[unstable(feature = "slice_binary_search_by_key", reason = "recently added", issue = "33018")]
|
|
||||||
fn binary_search_by_key<B, F>(&self, b: &B, f: F) -> Result<usize, usize>
|
|
||||||
where F: FnMut(&Self::Item) -> B,
|
|
||||||
B: Ord;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use macros to be generic over const/mut
|
// Use macros to be generic over const/mut
|
||||||
|
|
|
@ -299,7 +299,6 @@ impl AtomicBool {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(extended_compare_and_swap)]
|
|
||||||
/// use std::sync::atomic::{AtomicBool, Ordering};
|
/// use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
///
|
///
|
||||||
/// let some_bool = AtomicBool::new(true);
|
/// let some_bool = AtomicBool::new(true);
|
||||||
|
@ -318,7 +317,7 @@ impl AtomicBool {
|
||||||
/// assert_eq!(some_bool.load(Ordering::Relaxed), false);
|
/// assert_eq!(some_bool.load(Ordering::Relaxed), false);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")]
|
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||||
pub fn compare_exchange(&self,
|
pub fn compare_exchange(&self,
|
||||||
current: bool,
|
current: bool,
|
||||||
new: bool,
|
new: bool,
|
||||||
|
@ -347,7 +346,6 @@ impl AtomicBool {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(extended_compare_and_swap)]
|
|
||||||
/// use std::sync::atomic::{AtomicBool, Ordering};
|
/// use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
///
|
///
|
||||||
/// let val = AtomicBool::new(false);
|
/// let val = AtomicBool::new(false);
|
||||||
|
@ -362,7 +360,7 @@ impl AtomicBool {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")]
|
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||||
pub fn compare_exchange_weak(&self,
|
pub fn compare_exchange_weak(&self,
|
||||||
current: bool,
|
current: bool,
|
||||||
new: bool,
|
new: bool,
|
||||||
|
@ -645,7 +643,6 @@ impl<T> AtomicPtr<T> {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(extended_compare_and_swap)]
|
|
||||||
/// use std::sync::atomic::{AtomicPtr, Ordering};
|
/// use std::sync::atomic::{AtomicPtr, Ordering};
|
||||||
///
|
///
|
||||||
/// let ptr = &mut 5;
|
/// let ptr = &mut 5;
|
||||||
|
@ -658,7 +655,7 @@ impl<T> AtomicPtr<T> {
|
||||||
/// Ordering::SeqCst, Ordering::Relaxed);
|
/// Ordering::SeqCst, Ordering::Relaxed);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")]
|
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||||
pub fn compare_exchange(&self,
|
pub fn compare_exchange(&self,
|
||||||
current: *mut T,
|
current: *mut T,
|
||||||
new: *mut T,
|
new: *mut T,
|
||||||
|
@ -693,7 +690,6 @@ impl<T> AtomicPtr<T> {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(extended_compare_and_swap)]
|
|
||||||
/// use std::sync::atomic::{AtomicPtr, Ordering};
|
/// use std::sync::atomic::{AtomicPtr, Ordering};
|
||||||
///
|
///
|
||||||
/// let some_ptr = AtomicPtr::new(&mut 5);
|
/// let some_ptr = AtomicPtr::new(&mut 5);
|
||||||
|
@ -708,7 +704,7 @@ impl<T> AtomicPtr<T> {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")]
|
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||||
pub fn compare_exchange_weak(&self,
|
pub fn compare_exchange_weak(&self,
|
||||||
current: *mut T,
|
current: *mut T,
|
||||||
new: *mut T,
|
new: *mut T,
|
||||||
|
@ -901,7 +897,6 @@ macro_rules! atomic_int {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(extended_compare_and_swap)]
|
|
||||||
/// use std::sync::atomic::{AtomicIsize, Ordering};
|
/// use std::sync::atomic::{AtomicIsize, Ordering};
|
||||||
///
|
///
|
||||||
/// let some_isize = AtomicIsize::new(5);
|
/// let some_isize = AtomicIsize::new(5);
|
||||||
|
@ -945,7 +940,6 @@ macro_rules! atomic_int {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(extended_compare_and_swap)]
|
|
||||||
/// use std::sync::atomic::{AtomicIsize, Ordering};
|
/// use std::sync::atomic::{AtomicIsize, Ordering};
|
||||||
///
|
///
|
||||||
/// let val = AtomicIsize::new(4);
|
/// let val = AtomicIsize::new(4);
|
||||||
|
@ -1115,14 +1109,14 @@ atomic_int! {
|
||||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||||
atomic_int!{
|
atomic_int!{
|
||||||
stable(feature = "rust1", since = "1.0.0"),
|
stable(feature = "rust1", since = "1.0.0"),
|
||||||
unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767"),
|
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
||||||
stable(feature = "atomic_debug", since = "1.3.0"),
|
stable(feature = "atomic_debug", since = "1.3.0"),
|
||||||
isize AtomicIsize ATOMIC_ISIZE_INIT
|
isize AtomicIsize ATOMIC_ISIZE_INIT
|
||||||
}
|
}
|
||||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||||
atomic_int!{
|
atomic_int!{
|
||||||
stable(feature = "rust1", since = "1.0.0"),
|
stable(feature = "rust1", since = "1.0.0"),
|
||||||
unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767"),
|
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
||||||
stable(feature = "atomic_debug", since = "1.3.0"),
|
stable(feature = "atomic_debug", since = "1.3.0"),
|
||||||
usize AtomicUsize ATOMIC_USIZE_INIT
|
usize AtomicUsize ATOMIC_USIZE_INIT
|
||||||
}
|
}
|
||||||
|
|
|
@ -902,15 +902,6 @@ fn test_range_step() {
|
||||||
assert_eq!((isize::MIN..isize::MAX).step_by(1).size_hint(), (usize::MAX, Some(usize::MAX)));
|
assert_eq!((isize::MIN..isize::MAX).step_by(1).size_hint(), (usize::MAX, Some(usize::MAX)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_peekable_is_empty() {
|
|
||||||
let a = [1];
|
|
||||||
let mut it = a.iter().peekable();
|
|
||||||
assert!( !it.is_empty() );
|
|
||||||
it.next();
|
|
||||||
assert!( it.is_empty() );
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_repeat() {
|
fn test_repeat() {
|
||||||
let mut it = repeat(42);
|
let mut it = repeat(42);
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#![feature(iter_arith)]
|
#![feature(iter_arith)]
|
||||||
#![feature(libc)]
|
#![feature(libc)]
|
||||||
#![feature(nonzero)]
|
#![feature(nonzero)]
|
||||||
#![feature(peekable_is_empty)]
|
|
||||||
#![feature(rand)]
|
#![feature(rand)]
|
||||||
#![feature(raw)]
|
#![feature(raw)]
|
||||||
#![feature(slice_patterns)]
|
#![feature(slice_patterns)]
|
||||||
|
|
|
@ -170,10 +170,7 @@
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![cfg_attr(not(stage0), deny(warnings))]
|
#![cfg_attr(not(stage0), deny(warnings))]
|
||||||
|
|
||||||
#![feature(box_syntax)]
|
|
||||||
#![feature(const_fn)]
|
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(static_mutex)]
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -181,9 +178,8 @@ use std::io::{self, Stderr};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ptr;
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::{Once, StaticMutex};
|
use std::sync::{Once, Mutex, ONCE_INIT};
|
||||||
|
|
||||||
use directive::LOG_LEVEL_NAMES;
|
use directive::LOG_LEVEL_NAMES;
|
||||||
|
|
||||||
|
@ -199,18 +195,13 @@ pub const MAX_LOG_LEVEL: u32 = 255;
|
||||||
/// The default logging level of a crate if no other is specified.
|
/// The default logging level of a crate if no other is specified.
|
||||||
const DEFAULT_LOG_LEVEL: u32 = 1;
|
const DEFAULT_LOG_LEVEL: u32 = 1;
|
||||||
|
|
||||||
static LOCK: StaticMutex = StaticMutex::new();
|
static mut LOCK: *mut Mutex<(Vec<directive::LogDirective>, Option<String>)> = 0 as *mut _;
|
||||||
|
|
||||||
/// An unsafe constant that is the maximum logging level of any module
|
/// An unsafe constant that is the maximum logging level of any module
|
||||||
/// specified. This is the first line of defense to determining whether a
|
/// specified. This is the first line of defense to determining whether a
|
||||||
/// logging statement should be run.
|
/// logging statement should be run.
|
||||||
static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;
|
static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;
|
||||||
|
|
||||||
static mut DIRECTIVES: *mut Vec<directive::LogDirective> = ptr::null_mut();
|
|
||||||
|
|
||||||
/// Optional filter.
|
|
||||||
static mut FILTER: *mut String = ptr::null_mut();
|
|
||||||
|
|
||||||
/// Debug log level
|
/// Debug log level
|
||||||
pub const DEBUG: u32 = 4;
|
pub const DEBUG: u32 = 4;
|
||||||
/// Info log level
|
/// Info log level
|
||||||
|
@ -287,14 +278,10 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
|
||||||
// Test the literal string from args against the current filter, if there
|
// Test the literal string from args against the current filter, if there
|
||||||
// is one.
|
// is one.
|
||||||
unsafe {
|
unsafe {
|
||||||
let _g = LOCK.lock();
|
let filter = (*LOCK).lock().unwrap();
|
||||||
match FILTER as usize {
|
if let Some(ref filter) = filter.1 {
|
||||||
0 => {}
|
if !args.to_string().contains(filter) {
|
||||||
n => {
|
return;
|
||||||
let filter = mem::transmute::<_, &String>(n);
|
|
||||||
if !args.to_string().contains(filter) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,10 +289,10 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
|
||||||
// Completely remove the local logger from TLS in case anyone attempts to
|
// Completely remove the local logger from TLS in case anyone attempts to
|
||||||
// frob the slot while we're doing the logging. This will destroy any logger
|
// frob the slot while we're doing the logging. This will destroy any logger
|
||||||
// set during logging.
|
// set during logging.
|
||||||
let mut logger: Box<Logger + Send> = LOCAL_LOGGER.with(|s| s.borrow_mut().take())
|
let logger = LOCAL_LOGGER.with(|s| s.borrow_mut().take());
|
||||||
.unwrap_or_else(|| {
|
let mut logger = logger.unwrap_or_else(|| {
|
||||||
box DefaultLogger { handle: io::stderr() }
|
Box::new(DefaultLogger { handle: io::stderr() })
|
||||||
});
|
});
|
||||||
logger.log(&LogRecord {
|
logger.log(&LogRecord {
|
||||||
level: LogLevel(level),
|
level: LogLevel(level),
|
||||||
args: args,
|
args: args,
|
||||||
|
@ -363,7 +350,7 @@ pub struct LogLocation {
|
||||||
/// module's log statement should be emitted or not.
|
/// module's log statement should be emitted or not.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn mod_enabled(level: u32, module: &str) -> bool {
|
pub fn mod_enabled(level: u32, module: &str) -> bool {
|
||||||
static INIT: Once = Once::new();
|
static INIT: Once = ONCE_INIT;
|
||||||
INIT.call_once(init);
|
INIT.call_once(init);
|
||||||
|
|
||||||
// It's possible for many threads are in this function, only one of them
|
// It's possible for many threads are in this function, only one of them
|
||||||
|
@ -378,10 +365,9 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
|
||||||
// This assertion should never get tripped unless we're in an at_exit
|
// This assertion should never get tripped unless we're in an at_exit
|
||||||
// handler after logging has been torn down and a logging attempt was made.
|
// handler after logging has been torn down and a logging attempt was made.
|
||||||
|
|
||||||
let _g = LOCK.lock();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(DIRECTIVES as usize != 0);
|
let directives = (*LOCK).lock().unwrap();
|
||||||
enabled(level, module, (*DIRECTIVES).iter())
|
enabled(level, module, directives.0.iter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,14 +408,8 @@ fn init() {
|
||||||
unsafe {
|
unsafe {
|
||||||
LOG_LEVEL = max_level;
|
LOG_LEVEL = max_level;
|
||||||
|
|
||||||
assert!(FILTER.is_null());
|
assert!(LOCK.is_null());
|
||||||
match filter {
|
LOCK = Box::into_raw(Box::new(Mutex::new((directives, filter))));
|
||||||
Some(f) => FILTER = Box::into_raw(box f),
|
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(DIRECTIVES.is_null());
|
|
||||||
DIRECTIVES = Box::into_raw(box directives);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,12 +189,16 @@ mod dl {
|
||||||
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
|
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
|
||||||
F: FnOnce() -> T,
|
F: FnOnce() -> T,
|
||||||
{
|
{
|
||||||
use std::sync::StaticMutex;
|
use std::sync::{Mutex, Once, ONCE_INIT};
|
||||||
static LOCK: StaticMutex = StaticMutex::new();
|
static INIT: Once = ONCE_INIT;
|
||||||
|
static mut LOCK: *mut Mutex<()> = 0 as *mut _;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
INIT.call_once(|| {
|
||||||
|
LOCK = Box::into_raw(Box::new(Mutex::new(())));
|
||||||
|
});
|
||||||
// dlerror isn't thread safe, so we need to lock around this entire
|
// dlerror isn't thread safe, so we need to lock around this entire
|
||||||
// sequence
|
// sequence
|
||||||
let _guard = LOCK.lock();
|
let _guard = (*LOCK).lock();
|
||||||
let _old_error = libc::dlerror();
|
let _old_error = libc::dlerror();
|
||||||
|
|
||||||
let result = f();
|
let result = f();
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(step_by)]
|
#![feature(step_by)]
|
||||||
#![feature(question_mark)]
|
#![feature(question_mark)]
|
||||||
#![cfg_attr(unix, feature(static_mutex))]
|
|
||||||
#![cfg_attr(test, feature(test, rand))]
|
#![cfg_attr(test, feature(test, rand))]
|
||||||
|
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
|
|
@ -864,7 +864,6 @@ impl<K, V, S> HashMap<K, V, S>
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(map_values_mut)]
|
|
||||||
/// use std::collections::HashMap;
|
/// use std::collections::HashMap;
|
||||||
///
|
///
|
||||||
/// let mut map = HashMap::new();
|
/// let mut map = HashMap::new();
|
||||||
|
@ -881,8 +880,8 @@ impl<K, V, S> HashMap<K, V, S>
|
||||||
/// print!("{}", val);
|
/// print!("{}", val);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
pub fn values_mut<'a>(&'a mut self) -> ValuesMut<K, V> {
|
pub fn values_mut(&mut self) -> ValuesMut<K, V> {
|
||||||
ValuesMut { inner: self.iter_mut() }
|
ValuesMut { inner: self.iter_mut() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1288,7 +1287,7 @@ pub struct Drain<'a, K: 'a, V: 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable HashMap values iterator.
|
/// Mutable HashMap values iterator.
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
pub struct ValuesMut<'a, K: 'a, V: 'a> {
|
pub struct ValuesMut<'a, K: 'a, V: 'a> {
|
||||||
inner: IterMut<'a, K, V>
|
inner: IterMut<'a, K, V>
|
||||||
}
|
}
|
||||||
|
@ -1491,14 +1490,14 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
|
||||||
#[inline] fn len(&self) -> usize { self.inner.len() }
|
#[inline] fn len(&self) -> usize { self.inner.len() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
|
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
|
||||||
type Item = &'a mut V;
|
type Item = &'a mut V;
|
||||||
|
|
||||||
#[inline] fn next(&mut self) -> Option<(&'a mut V)> { self.inner.next().map(|(_, v)| v) }
|
#[inline] fn next(&mut self) -> Option<(&'a mut V)> { self.inner.next().map(|(_, v)| v) }
|
||||||
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
|
||||||
}
|
}
|
||||||
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
|
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||||
impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
|
impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
|
||||||
#[inline] fn len(&self) -> usize { self.inner.len() }
|
#[inline] fn len(&self) -> usize { self.inner.len() }
|
||||||
}
|
}
|
||||||
|
@ -1537,7 +1536,7 @@ impl<'a, K, V> Entry<'a, K, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to this entry's key.
|
/// Returns a reference to this entry's key.
|
||||||
#[unstable(feature = "map_entry_keys", issue = "32281")]
|
#[stable(feature = "map_entry_keys", since = "1.10.0")]
|
||||||
pub fn key(&self) -> &K {
|
pub fn key(&self) -> &K {
|
||||||
match *self {
|
match *self {
|
||||||
Occupied(ref entry) => entry.key(),
|
Occupied(ref entry) => entry.key(),
|
||||||
|
@ -1548,7 +1547,7 @@ impl<'a, K, V> Entry<'a, K, V> {
|
||||||
|
|
||||||
impl<'a, K, V> OccupiedEntry<'a, K, V> {
|
impl<'a, K, V> OccupiedEntry<'a, K, V> {
|
||||||
/// Gets a reference to the key in the entry.
|
/// Gets a reference to the key in the entry.
|
||||||
#[unstable(feature = "map_entry_keys", issue = "32281")]
|
#[stable(feature = "map_entry_keys", since = "1.10.0")]
|
||||||
pub fn key(&self) -> &K {
|
pub fn key(&self) -> &K {
|
||||||
self.elem.read().0
|
self.elem.read().0
|
||||||
}
|
}
|
||||||
|
@ -1596,7 +1595,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
|
||||||
impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
|
impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
|
||||||
/// Gets a reference to the key that would be used when inserting a value
|
/// Gets a reference to the key that would be used when inserting a value
|
||||||
/// through the VacantEntry.
|
/// through the VacantEntry.
|
||||||
#[unstable(feature = "map_entry_keys", issue = "32281")]
|
#[stable(feature = "map_entry_keys", since = "1.10.0")]
|
||||||
pub fn key(&self) -> &K {
|
pub fn key(&self) -> &K {
|
||||||
&self.key
|
&self.key
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,12 @@ pub struct CStr {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct NulError(usize, Vec<u8>);
|
pub struct NulError(usize, Vec<u8>);
|
||||||
|
|
||||||
|
/// An error returned from `CStr::from_bytes_with_nul` to indicate that a nul
|
||||||
|
/// byte was found too early in the slice provided or one wasn't found at all.
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||||
|
pub struct FromBytesWithNulError { _a: () }
|
||||||
|
|
||||||
/// An error returned from `CString::into_string` to indicate that a UTF-8 error
|
/// An error returned from `CString::into_string` to indicate that a UTF-8 error
|
||||||
/// was encountered during the conversion.
|
/// was encountered during the conversion.
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
@ -461,20 +467,18 @@ impl CStr {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(cstr_from_bytes)]
|
|
||||||
/// use std::ffi::CStr;
|
/// use std::ffi::CStr;
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
|
||||||
/// let cstr = CStr::from_bytes_with_nul(b"hello\0");
|
/// let cstr = CStr::from_bytes_with_nul(b"hello\0");
|
||||||
/// assert!(cstr.is_some());
|
/// assert!(cstr.is_ok());
|
||||||
/// # }
|
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "cstr_from_bytes", reason = "recently added", issue = "31190")]
|
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||||
pub fn from_bytes_with_nul(bytes: &[u8]) -> Option<&CStr> {
|
pub fn from_bytes_with_nul(bytes: &[u8])
|
||||||
|
-> Result<&CStr, FromBytesWithNulError> {
|
||||||
if bytes.is_empty() || memchr::memchr(0, &bytes) != Some(bytes.len() - 1) {
|
if bytes.is_empty() || memchr::memchr(0, &bytes) != Some(bytes.len() - 1) {
|
||||||
None
|
Err(FromBytesWithNulError { _a: () })
|
||||||
} else {
|
} else {
|
||||||
Some(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
|
Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,18 +491,15 @@ impl CStr {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(cstr_from_bytes)]
|
|
||||||
/// use std::ffi::{CStr, CString};
|
/// use std::ffi::{CStr, CString};
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
|
||||||
/// unsafe {
|
/// unsafe {
|
||||||
/// let cstring = CString::new("hello").unwrap();
|
/// let cstring = CString::new("hello").unwrap();
|
||||||
/// let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul());
|
/// let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul());
|
||||||
/// assert_eq!(cstr, &*cstring);
|
/// assert_eq!(cstr, &*cstring);
|
||||||
/// }
|
/// }
|
||||||
/// # }
|
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "cstr_from_bytes", reason = "recently added", issue = "31190")]
|
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||||
pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
|
pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
|
||||||
mem::transmute(bytes)
|
mem::transmute(bytes)
|
||||||
}
|
}
|
||||||
|
@ -742,12 +743,14 @@ mod tests {
|
||||||
fn from_bytes_with_nul() {
|
fn from_bytes_with_nul() {
|
||||||
let data = b"123\0";
|
let data = b"123\0";
|
||||||
let cstr = CStr::from_bytes_with_nul(data);
|
let cstr = CStr::from_bytes_with_nul(data);
|
||||||
assert_eq!(cstr.map(CStr::to_bytes), Some(&b"123"[..]));
|
assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
|
||||||
assert_eq!(cstr.map(CStr::to_bytes_with_nul), Some(&b"123\0"[..]));
|
let cstr = CStr::from_bytes_with_nul(data);
|
||||||
|
assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let cstr = CStr::from_bytes_with_nul(data);
|
||||||
let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
|
let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
|
||||||
assert_eq!(cstr, Some(cstr_unchecked));
|
assert_eq!(cstr, Ok(cstr_unchecked));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,13 +758,13 @@ mod tests {
|
||||||
fn from_bytes_with_nul_unterminated() {
|
fn from_bytes_with_nul_unterminated() {
|
||||||
let data = b"123";
|
let data = b"123";
|
||||||
let cstr = CStr::from_bytes_with_nul(data);
|
let cstr = CStr::from_bytes_with_nul(data);
|
||||||
assert!(cstr.is_none());
|
assert!(cstr.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_bytes_with_nul_interior() {
|
fn from_bytes_with_nul_interior() {
|
||||||
let data = b"1\023\0";
|
let data = b"1\023\0";
|
||||||
let cstr = CStr::from_bytes_with_nul(data);
|
let cstr = CStr::from_bytes_with_nul(data);
|
||||||
assert!(cstr.is_none());
|
assert!(cstr.is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::c_str::{CString, CStr, NulError, IntoStringError};
|
pub use self::c_str::{CString, CStr, NulError, IntoStringError};
|
||||||
|
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||||
|
pub use self::c_str::{FromBytesWithNulError};
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::os_str::{OsString, OsStr};
|
pub use self::os_str::{OsString, OsStr};
|
||||||
|
|
|
@ -657,7 +657,7 @@ impl Metadata {
|
||||||
///
|
///
|
||||||
/// This field may not be available on all platforms, and will return an
|
/// This field may not be available on all platforms, and will return an
|
||||||
/// `Err` on platforms where it is not available.
|
/// `Err` on platforms where it is not available.
|
||||||
#[unstable(feature = "fs_time", issue = "31399")]
|
#[stable(feature = "fs_time", since = "1.10.0")]
|
||||||
pub fn modified(&self) -> io::Result<SystemTime> {
|
pub fn modified(&self) -> io::Result<SystemTime> {
|
||||||
self.0.modified().map(FromInner::from_inner)
|
self.0.modified().map(FromInner::from_inner)
|
||||||
}
|
}
|
||||||
|
@ -675,7 +675,7 @@ impl Metadata {
|
||||||
///
|
///
|
||||||
/// This field may not be available on all platforms, and will return an
|
/// This field may not be available on all platforms, and will return an
|
||||||
/// `Err` on platforms where it is not available.
|
/// `Err` on platforms where it is not available.
|
||||||
#[unstable(feature = "fs_time", issue = "31399")]
|
#[stable(feature = "fs_time", since = "1.10.0")]
|
||||||
pub fn accessed(&self) -> io::Result<SystemTime> {
|
pub fn accessed(&self) -> io::Result<SystemTime> {
|
||||||
self.0.accessed().map(FromInner::from_inner)
|
self.0.accessed().map(FromInner::from_inner)
|
||||||
}
|
}
|
||||||
|
@ -689,7 +689,7 @@ impl Metadata {
|
||||||
///
|
///
|
||||||
/// This field may not be available on all platforms, and will return an
|
/// This field may not be available on all platforms, and will return an
|
||||||
/// `Err` on platforms where it is not available.
|
/// `Err` on platforms where it is not available.
|
||||||
#[unstable(feature = "fs_time", issue = "31399")]
|
#[stable(feature = "fs_time", since = "1.10.0")]
|
||||||
pub fn created(&self) -> io::Result<SystemTime> {
|
pub fn created(&self) -> io::Result<SystemTime> {
|
||||||
self.0.created().map(FromInner::from_inner)
|
self.0.created().map(FromInner::from_inner)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,12 @@ use prelude::v1::*;
|
||||||
|
|
||||||
use cell::Cell;
|
use cell::Cell;
|
||||||
use ptr;
|
use ptr;
|
||||||
use sync::{StaticMutex, Arc};
|
use sync::Arc;
|
||||||
use sys_common;
|
use sys_common;
|
||||||
|
use sys_common::mutex::Mutex;
|
||||||
|
|
||||||
pub struct Lazy<T> {
|
pub struct Lazy<T> {
|
||||||
lock: StaticMutex,
|
lock: Mutex,
|
||||||
ptr: Cell<*mut Arc<T>>,
|
ptr: Cell<*mut Arc<T>>,
|
||||||
init: fn() -> Arc<T>,
|
init: fn() -> Arc<T>,
|
||||||
}
|
}
|
||||||
|
@ -26,23 +27,25 @@ unsafe impl<T> Sync for Lazy<T> {}
|
||||||
impl<T: Send + Sync + 'static> Lazy<T> {
|
impl<T: Send + Sync + 'static> Lazy<T> {
|
||||||
pub const fn new(init: fn() -> Arc<T>) -> Lazy<T> {
|
pub const fn new(init: fn() -> Arc<T>) -> Lazy<T> {
|
||||||
Lazy {
|
Lazy {
|
||||||
lock: StaticMutex::new(),
|
lock: Mutex::new(),
|
||||||
ptr: Cell::new(ptr::null_mut()),
|
ptr: Cell::new(ptr::null_mut()),
|
||||||
init: init
|
init: init
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&'static self) -> Option<Arc<T>> {
|
pub fn get(&'static self) -> Option<Arc<T>> {
|
||||||
let _g = self.lock.lock();
|
|
||||||
let ptr = self.ptr.get();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if ptr.is_null() {
|
self.lock.lock();
|
||||||
|
let ptr = self.ptr.get();
|
||||||
|
let ret = if ptr.is_null() {
|
||||||
Some(self.init())
|
Some(self.init())
|
||||||
} else if ptr as usize == 1 {
|
} else if ptr as usize == 1 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((*ptr).clone())
|
Some((*ptr).clone())
|
||||||
}
|
};
|
||||||
|
self.lock.unlock();
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +55,10 @@ impl<T: Send + Sync + 'static> Lazy<T> {
|
||||||
// the at exit handler). Otherwise we just return the freshly allocated
|
// the at exit handler). Otherwise we just return the freshly allocated
|
||||||
// `Arc`.
|
// `Arc`.
|
||||||
let registered = sys_common::at_exit(move || {
|
let registered = sys_common::at_exit(move || {
|
||||||
let g = self.lock.lock();
|
self.lock.lock();
|
||||||
let ptr = self.ptr.get();
|
let ptr = self.ptr.get();
|
||||||
self.ptr.set(1 as *mut _);
|
self.ptr.set(1 as *mut _);
|
||||||
drop(g);
|
self.lock.unlock();
|
||||||
drop(Box::from_raw(ptr))
|
drop(Box::from_raw(ptr))
|
||||||
});
|
});
|
||||||
let ret = (self.init)();
|
let ret = (self.init)();
|
||||||
|
|
|
@ -22,7 +22,7 @@ use rc::Rc;
|
||||||
use sync::{Arc, Mutex, RwLock};
|
use sync::{Arc, Mutex, RwLock};
|
||||||
use thread::Result;
|
use thread::Result;
|
||||||
|
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub use panicking::{take_hook, set_hook, PanicInfo, Location};
|
pub use panicking::{take_hook, set_hook, PanicInfo, Location};
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
|
@ -27,7 +27,7 @@ use fmt;
|
||||||
use intrinsics;
|
use intrinsics;
|
||||||
use mem;
|
use mem;
|
||||||
use raw;
|
use raw;
|
||||||
use sync::StaticRwLock;
|
use sys_common::rwlock::RWLock;
|
||||||
use sync::atomic::{AtomicBool, Ordering};
|
use sync::atomic::{AtomicBool, Ordering};
|
||||||
use sys::stdio::Stderr;
|
use sys::stdio::Stderr;
|
||||||
use sys_common::backtrace;
|
use sys_common::backtrace;
|
||||||
|
@ -69,7 +69,7 @@ enum Hook {
|
||||||
Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)),
|
Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)),
|
||||||
}
|
}
|
||||||
|
|
||||||
static HOOK_LOCK: StaticRwLock = StaticRwLock::new();
|
static HOOK_LOCK: RWLock = RWLock::new();
|
||||||
static mut HOOK: Hook = Hook::Default;
|
static mut HOOK: Hook = Hook::Default;
|
||||||
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
|
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
|
||||||
|
|
||||||
|
@ -90,17 +90,17 @@ static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if called from a panicking thread.
|
/// Panics if called from a panicking thread.
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
|
pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
|
||||||
if thread::panicking() {
|
if thread::panicking() {
|
||||||
panic!("cannot modify the panic hook from a panicking thread");
|
panic!("cannot modify the panic hook from a panicking thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let lock = HOOK_LOCK.write();
|
HOOK_LOCK.write();
|
||||||
let old_hook = HOOK;
|
let old_hook = HOOK;
|
||||||
HOOK = Hook::Custom(Box::into_raw(hook));
|
HOOK = Hook::Custom(Box::into_raw(hook));
|
||||||
drop(lock);
|
HOOK_LOCK.write_unlock();
|
||||||
|
|
||||||
if let Hook::Custom(ptr) = old_hook {
|
if let Hook::Custom(ptr) = old_hook {
|
||||||
Box::from_raw(ptr);
|
Box::from_raw(ptr);
|
||||||
|
@ -115,17 +115,17 @@ pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if called from a panicking thread.
|
/// Panics if called from a panicking thread.
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
|
pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
|
||||||
if thread::panicking() {
|
if thread::panicking() {
|
||||||
panic!("cannot modify the panic hook from a panicking thread");
|
panic!("cannot modify the panic hook from a panicking thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let lock = HOOK_LOCK.write();
|
HOOK_LOCK.write();
|
||||||
let hook = HOOK;
|
let hook = HOOK;
|
||||||
HOOK = Hook::Default;
|
HOOK = Hook::Default;
|
||||||
drop(lock);
|
HOOK_LOCK.write_unlock();
|
||||||
|
|
||||||
match hook {
|
match hook {
|
||||||
Hook::Default => Box::new(default_hook),
|
Hook::Default => Box::new(default_hook),
|
||||||
|
@ -135,7 +135,7 @@ pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct providing information about a panic.
|
/// A struct providing information about a panic.
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub struct PanicInfo<'a> {
|
pub struct PanicInfo<'a> {
|
||||||
payload: &'a (Any + Send),
|
payload: &'a (Any + Send),
|
||||||
location: Location<'a>,
|
location: Location<'a>,
|
||||||
|
@ -145,7 +145,7 @@ impl<'a> PanicInfo<'a> {
|
||||||
/// Returns the payload associated with the panic.
|
/// Returns the payload associated with the panic.
|
||||||
///
|
///
|
||||||
/// This will commonly, but not always, be a `&'static str` or `String`.
|
/// This will commonly, but not always, be a `&'static str` or `String`.
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub fn payload(&self) -> &(Any + Send) {
|
pub fn payload(&self) -> &(Any + Send) {
|
||||||
self.payload
|
self.payload
|
||||||
}
|
}
|
||||||
|
@ -155,14 +155,14 @@ impl<'a> PanicInfo<'a> {
|
||||||
///
|
///
|
||||||
/// This method will currently always return `Some`, but this may change
|
/// This method will currently always return `Some`, but this may change
|
||||||
/// in future versions.
|
/// in future versions.
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub fn location(&self) -> Option<&Location> {
|
pub fn location(&self) -> Option<&Location> {
|
||||||
Some(&self.location)
|
Some(&self.location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct containing information about the location of a panic.
|
/// A struct containing information about the location of a panic.
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub struct Location<'a> {
|
pub struct Location<'a> {
|
||||||
file: &'a str,
|
file: &'a str,
|
||||||
line: u32,
|
line: u32,
|
||||||
|
@ -170,13 +170,13 @@ pub struct Location<'a> {
|
||||||
|
|
||||||
impl<'a> Location<'a> {
|
impl<'a> Location<'a> {
|
||||||
/// Returns the name of the source file from which the panic originated.
|
/// Returns the name of the source file from which the panic originated.
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub fn file(&self) -> &str {
|
pub fn file(&self) -> &str {
|
||||||
self.file
|
self.file
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the line number from which the panic originated.
|
/// Returns the line number from which the panic originated.
|
||||||
#[unstable(feature = "panic_handler", issue = "30449")]
|
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||||
pub fn line(&self) -> u32 {
|
pub fn line(&self) -> u32 {
|
||||||
self.line
|
self.line
|
||||||
}
|
}
|
||||||
|
@ -365,11 +365,12 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
|
||||||
line: line,
|
line: line,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let _lock = HOOK_LOCK.read();
|
HOOK_LOCK.read();
|
||||||
match HOOK {
|
match HOOK {
|
||||||
Hook::Default => default_hook(&info),
|
Hook::Default => default_hook(&info),
|
||||||
Hook::Custom(ptr) => (*ptr)(&info),
|
Hook::Custom(ptr) => (*ptr)(&info),
|
||||||
}
|
}
|
||||||
|
HOOK_LOCK.read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if panics > 0 {
|
if panics > 0 {
|
||||||
|
|
|
@ -72,6 +72,7 @@ impl WaitTimeoutResult {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub struct Condvar { inner: Box<StaticCondvar> }
|
pub struct Condvar { inner: Box<StaticCondvar> }
|
||||||
|
|
||||||
/// Statically allocated condition variables.
|
/// Statically allocated condition variables.
|
||||||
|
@ -91,6 +92,11 @@ pub struct Condvar { inner: Box<StaticCondvar> }
|
||||||
#[unstable(feature = "static_condvar",
|
#[unstable(feature = "static_condvar",
|
||||||
reason = "may be merged with Condvar in the future",
|
reason = "may be merged with Condvar in the future",
|
||||||
issue = "27717")]
|
issue = "27717")]
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `Condvar::new` in a static should \
|
||||||
|
suffice")]
|
||||||
pub struct StaticCondvar {
|
pub struct StaticCondvar {
|
||||||
inner: sys::Condvar,
|
inner: sys::Condvar,
|
||||||
mutex: AtomicUsize,
|
mutex: AtomicUsize,
|
||||||
|
@ -100,8 +106,15 @@ pub struct StaticCondvar {
|
||||||
#[unstable(feature = "static_condvar",
|
#[unstable(feature = "static_condvar",
|
||||||
reason = "may be merged with Condvar in the future",
|
reason = "may be merged with Condvar in the future",
|
||||||
issue = "27717")]
|
issue = "27717")]
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `Condvar::new` in a static should \
|
||||||
|
suffice")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub const CONDVAR_INIT: StaticCondvar = StaticCondvar::new();
|
pub const CONDVAR_INIT: StaticCondvar = StaticCondvar::new();
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl Condvar {
|
impl Condvar {
|
||||||
/// Creates a new condition variable which is ready to be waited on and
|
/// Creates a new condition variable which is ready to be waited on and
|
||||||
/// notified.
|
/// notified.
|
||||||
|
@ -228,12 +241,22 @@ impl Default for Condvar {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
impl Drop for Condvar {
|
impl Drop for Condvar {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe { self.inner.inner.destroy() }
|
unsafe { self.inner.inner.destroy() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `Condvar::new` in a static should \
|
||||||
|
suffice")]
|
||||||
|
#[unstable(feature = "static_condvar",
|
||||||
|
reason = "may be merged with Condvar in the future",
|
||||||
|
issue = "27717")]
|
||||||
|
#[allow(deprecated)]
|
||||||
impl StaticCondvar {
|
impl StaticCondvar {
|
||||||
/// Creates a new condition variable
|
/// Creates a new condition variable
|
||||||
#[unstable(feature = "static_condvar",
|
#[unstable(feature = "static_condvar",
|
||||||
|
@ -392,6 +415,7 @@ impl StaticCondvar {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[allow(deprecated)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use prelude::v1::*;
|
use prelude::v1::*;
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,13 @@ pub use core::sync::atomic;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::barrier::{Barrier, BarrierWaitResult};
|
pub use self::barrier::{Barrier, BarrierWaitResult};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub use self::condvar::{Condvar, StaticCondvar, WaitTimeoutResult, CONDVAR_INIT};
|
pub use self::condvar::{Condvar, StaticCondvar, WaitTimeoutResult, CONDVAR_INIT};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub use self::mutex::MUTEX_INIT;
|
pub use self::mutex::MUTEX_INIT;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
|
pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::once::{Once, OnceState, ONCE_INIT};
|
pub use self::once::{Once, OnceState, ONCE_INIT};
|
||||||
|
@ -37,6 +40,7 @@ pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResul
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
|
pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
|
pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
|
||||||
|
|
||||||
pub mod mpsc;
|
pub mod mpsc;
|
||||||
|
|
|
@ -113,6 +113,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
|
||||||
/// *guard += 1;
|
/// *guard += 1;
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub struct Mutex<T: ?Sized> {
|
pub struct Mutex<T: ?Sized> {
|
||||||
// Note that this static mutex is in a *box*, not inlined into the struct
|
// Note that this static mutex is in a *box*, not inlined into the struct
|
||||||
// itself. Once a native mutex has been used once, its address can never
|
// itself. Once a native mutex has been used once, its address can never
|
||||||
|
@ -156,6 +157,11 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
|
||||||
#[unstable(feature = "static_mutex",
|
#[unstable(feature = "static_mutex",
|
||||||
reason = "may be merged with Mutex in the future",
|
reason = "may be merged with Mutex in the future",
|
||||||
issue = "27717")]
|
issue = "27717")]
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `Mutex::new` in a static should \
|
||||||
|
suffice")]
|
||||||
pub struct StaticMutex {
|
pub struct StaticMutex {
|
||||||
lock: sys::Mutex,
|
lock: sys::Mutex,
|
||||||
poison: poison::Flag,
|
poison: poison::Flag,
|
||||||
|
@ -168,6 +174,7 @@ pub struct StaticMutex {
|
||||||
/// `Deref` and `DerefMut` implementations
|
/// `Deref` and `DerefMut` implementations
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub struct MutexGuard<'a, T: ?Sized + 'a> {
|
pub struct MutexGuard<'a, T: ?Sized + 'a> {
|
||||||
// funny underscores due to how Deref/DerefMut currently work (they
|
// funny underscores due to how Deref/DerefMut currently work (they
|
||||||
// disregard field privacy).
|
// disregard field privacy).
|
||||||
|
@ -184,8 +191,15 @@ impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
|
||||||
#[unstable(feature = "static_mutex",
|
#[unstable(feature = "static_mutex",
|
||||||
reason = "may be merged with Mutex in the future",
|
reason = "may be merged with Mutex in the future",
|
||||||
issue = "27717")]
|
issue = "27717")]
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `Mutex::new` in a static should \
|
||||||
|
suffice")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub const MUTEX_INIT: StaticMutex = StaticMutex::new();
|
pub const MUTEX_INIT: StaticMutex = StaticMutex::new();
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<T> Mutex<T> {
|
impl<T> Mutex<T> {
|
||||||
/// Creates a new mutex in an unlocked state ready for use.
|
/// Creates a new mutex in an unlocked state ready for use.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -197,6 +211,7 @@ impl<T> Mutex<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<T: ?Sized> Mutex<T> {
|
impl<T: ?Sized> Mutex<T> {
|
||||||
/// Acquires a mutex, blocking the current thread until it is able to do so.
|
/// Acquires a mutex, blocking the current thread until it is able to do so.
|
||||||
///
|
///
|
||||||
|
@ -307,6 +322,7 @@ impl<T: ?Sized> Mutex<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<T: ?Sized> Drop for Mutex<T> {
|
impl<T: ?Sized> Drop for Mutex<T> {
|
||||||
#[unsafe_destructor_blind_to_params]
|
#[unsafe_destructor_blind_to_params]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -346,6 +362,12 @@ static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
|
||||||
#[unstable(feature = "static_mutex",
|
#[unstable(feature = "static_mutex",
|
||||||
reason = "may be merged with Mutex in the future",
|
reason = "may be merged with Mutex in the future",
|
||||||
issue = "27717")]
|
issue = "27717")]
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `Mutex::new` in a static should \
|
||||||
|
suffice")]
|
||||||
|
#[allow(deprecated)]
|
||||||
impl StaticMutex {
|
impl StaticMutex {
|
||||||
/// Creates a new mutex in an unlocked state ready for use.
|
/// Creates a new mutex in an unlocked state ready for use.
|
||||||
pub const fn new() -> StaticMutex {
|
pub const fn new() -> StaticMutex {
|
||||||
|
@ -391,8 +413,8 @@ impl StaticMutex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
|
impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
|
||||||
|
|
||||||
unsafe fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
|
unsafe fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
|
||||||
-> LockResult<MutexGuard<'mutex, T>> {
|
-> LockResult<MutexGuard<'mutex, T>> {
|
||||||
poison::map_result(lock.poison.borrow(), |guard| {
|
poison::map_result(lock.poison.borrow(), |guard| {
|
||||||
|
@ -418,6 +440,7 @@ impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -428,15 +451,18 @@ impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
|
pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
|
||||||
&guard.__lock.lock
|
&guard.__lock.lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
|
pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
|
||||||
&guard.__lock.poison
|
&guard.__lock.poison
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[allow(deprecated)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use prelude::v1::*;
|
use prelude::v1::*;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ use sys_common::rwlock as sys;
|
||||||
/// } // write lock is dropped here
|
/// } // write lock is dropped here
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub struct RwLock<T: ?Sized> {
|
pub struct RwLock<T: ?Sized> {
|
||||||
inner: Box<StaticRwLock>,
|
inner: Box<StaticRwLock>,
|
||||||
data: UnsafeCell<T>,
|
data: UnsafeCell<T>,
|
||||||
|
@ -104,6 +105,11 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
|
||||||
#[unstable(feature = "static_rwlock",
|
#[unstable(feature = "static_rwlock",
|
||||||
reason = "may be merged with RwLock in the future",
|
reason = "may be merged with RwLock in the future",
|
||||||
issue = "27717")]
|
issue = "27717")]
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `RwLock::new` in a static should \
|
||||||
|
suffice")]
|
||||||
pub struct StaticRwLock {
|
pub struct StaticRwLock {
|
||||||
lock: sys::RWLock,
|
lock: sys::RWLock,
|
||||||
poison: poison::Flag,
|
poison: poison::Flag,
|
||||||
|
@ -113,12 +119,19 @@ pub struct StaticRwLock {
|
||||||
#[unstable(feature = "static_rwlock",
|
#[unstable(feature = "static_rwlock",
|
||||||
reason = "may be merged with RwLock in the future",
|
reason = "may be merged with RwLock in the future",
|
||||||
issue = "27717")]
|
issue = "27717")]
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `RwLock::new` in a static should \
|
||||||
|
suffice")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock::new();
|
pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock::new();
|
||||||
|
|
||||||
/// RAII structure used to release the shared read access of a lock when
|
/// RAII structure used to release the shared read access of a lock when
|
||||||
/// dropped.
|
/// dropped.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
|
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
|
||||||
__lock: &'a StaticRwLock,
|
__lock: &'a StaticRwLock,
|
||||||
__data: &'a T,
|
__data: &'a T,
|
||||||
|
@ -131,6 +144,7 @@ impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
|
||||||
/// dropped.
|
/// dropped.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
|
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
|
||||||
__lock: &'a StaticRwLock,
|
__lock: &'a StaticRwLock,
|
||||||
__data: &'a mut T,
|
__data: &'a mut T,
|
||||||
|
@ -140,6 +154,7 @@ pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {}
|
impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<T> RwLock<T> {
|
impl<T> RwLock<T> {
|
||||||
/// Creates a new instance of an `RwLock<T>` which is unlocked.
|
/// Creates a new instance of an `RwLock<T>` which is unlocked.
|
||||||
///
|
///
|
||||||
|
@ -156,6 +171,7 @@ impl<T> RwLock<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<T: ?Sized> RwLock<T> {
|
impl<T: ?Sized> RwLock<T> {
|
||||||
/// Locks this rwlock with shared read access, blocking the current thread
|
/// Locks this rwlock with shared read access, blocking the current thread
|
||||||
/// until it can be acquired.
|
/// until it can be acquired.
|
||||||
|
@ -325,6 +341,7 @@ impl<T: ?Sized> RwLock<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<T: ?Sized> Drop for RwLock<T> {
|
impl<T: ?Sized> Drop for RwLock<T> {
|
||||||
#[unsafe_destructor_blind_to_params]
|
#[unsafe_destructor_blind_to_params]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -360,6 +377,12 @@ static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
|
||||||
#[unstable(feature = "static_rwlock",
|
#[unstable(feature = "static_rwlock",
|
||||||
reason = "may be merged with RwLock in the future",
|
reason = "may be merged with RwLock in the future",
|
||||||
issue = "27717")]
|
issue = "27717")]
|
||||||
|
#[rustc_deprecated(since = "1.10.0",
|
||||||
|
reason = "the lazy-static crate suffices for static sync \
|
||||||
|
primitives and eventually this type shouldn't \
|
||||||
|
be necessary as `RwLock::new` in a static should \
|
||||||
|
suffice")]
|
||||||
|
#[allow(deprecated)]
|
||||||
impl StaticRwLock {
|
impl StaticRwLock {
|
||||||
/// Creates a new rwlock.
|
/// Creates a new rwlock.
|
||||||
pub const fn new() -> StaticRwLock {
|
pub const fn new() -> StaticRwLock {
|
||||||
|
@ -434,6 +457,7 @@ impl StaticRwLock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
|
impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
|
||||||
unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
|
unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
|
||||||
-> LockResult<RwLockReadGuard<'rwlock, T>> {
|
-> LockResult<RwLockReadGuard<'rwlock, T>> {
|
||||||
|
@ -482,6 +506,7 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
|
impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
|
||||||
unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
|
unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
|
||||||
-> LockResult<RwLockWriteGuard<'rwlock, T>> {
|
-> LockResult<RwLockWriteGuard<'rwlock, T>> {
|
||||||
|
@ -562,10 +587,12 @@ impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> {
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
|
impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
|
||||||
fn deref_mut(&mut self) -> &mut T { self.__data
|
fn deref_mut(&mut self) -> &mut T {
|
||||||
|
self.__data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -573,6 +600,7 @@ impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
|
impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -582,6 +610,7 @@ impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[allow(deprecated)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(deprecated)] // rand
|
#![allow(deprecated)] // rand
|
||||||
|
|
||||||
|
|
|
@ -48,32 +48,36 @@ mod imp {
|
||||||
use mem;
|
use mem;
|
||||||
use ffi::CStr;
|
use ffi::CStr;
|
||||||
|
|
||||||
use sync::StaticMutex;
|
use sys_common::mutex::Mutex;
|
||||||
|
|
||||||
static mut GLOBAL_ARGS_PTR: usize = 0;
|
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) {
|
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||||
let args = (0..argc).map(|i| {
|
let args = (0..argc).map(|i| {
|
||||||
CStr::from_ptr(*argv.offset(i) as *const c_char).to_bytes().to_vec()
|
CStr::from_ptr(*argv.offset(i) as *const c_char).to_bytes().to_vec()
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let _guard = LOCK.lock();
|
LOCK.lock();
|
||||||
let ptr = get_global_ptr();
|
let ptr = get_global_ptr();
|
||||||
assert!((*ptr).is_none());
|
assert!((*ptr).is_none());
|
||||||
(*ptr) = Some(box args);
|
(*ptr) = Some(box args);
|
||||||
|
LOCK.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn cleanup() {
|
pub unsafe fn cleanup() {
|
||||||
let _guard = LOCK.lock();
|
LOCK.lock();
|
||||||
*get_global_ptr() = None;
|
*get_global_ptr() = None;
|
||||||
|
LOCK.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone() -> Option<Vec<Vec<u8>>> {
|
pub fn clone() -> Option<Vec<Vec<u8>>> {
|
||||||
let _guard = LOCK.lock();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
LOCK.lock();
|
||||||
let ptr = get_global_ptr();
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,11 @@
|
||||||
/// simple to use it should be used only on iOS devices as the only viable
|
/// simple to use it should be used only on iOS devices as the only viable
|
||||||
/// option.
|
/// option.
|
||||||
|
|
||||||
use io;
|
|
||||||
use io::prelude::*;
|
use io::prelude::*;
|
||||||
|
use io;
|
||||||
use libc;
|
use libc;
|
||||||
use mem;
|
use mem;
|
||||||
use result::Result::Ok;
|
use sys::mutex::Mutex;
|
||||||
use sync::StaticMutex;
|
|
||||||
|
|
||||||
use super::super::printing::print;
|
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
|
// while it doesn't requires lock for work as everything is
|
||||||
// local, it still displays much nicer backtraces when a
|
// local, it still displays much nicer backtraces when a
|
||||||
// couple of threads panic simultaneously
|
// couple of threads panic simultaneously
|
||||||
static LOCK: StaticMutex = StaticMutex::new();
|
static LOCK: Mutex = Mutex::new();
|
||||||
let _g = LOCK.lock();
|
unsafe {
|
||||||
|
LOCK.lock();
|
||||||
|
|
||||||
writeln!(w, "stack backtrace:")?;
|
writeln!(w, "stack backtrace:")?;
|
||||||
// 100 lines should be enough
|
// 100 lines should be enough
|
||||||
const SIZE: usize = 100;
|
const SIZE: usize = 100;
|
||||||
let mut buf: [*mut libc::c_void; SIZE] = unsafe { mem::zeroed() };
|
let mut buf: [*mut libc::c_void; SIZE] = mem::zeroed();
|
||||||
let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as usize};
|
let cnt = backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as usize;
|
||||||
|
|
||||||
// skipping the first one as it is write itself
|
// skipping the first one as it is write itself
|
||||||
for i in 1..cnt {
|
for i in 1..cnt {
|
||||||
print(w, i as isize, buf[i], buf[i])?
|
print(w, i as isize, buf[i], buf[i])?
|
||||||
|
}
|
||||||
|
LOCK.unlock();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use io;
|
||||||
use io::prelude::*;
|
use io::prelude::*;
|
||||||
use libc;
|
use libc;
|
||||||
use mem;
|
use mem;
|
||||||
use sync::StaticMutex;
|
use sys_common::mutex::Mutex;
|
||||||
|
|
||||||
use super::super::printing::print;
|
use super::super::printing::print;
|
||||||
use unwind as uw;
|
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
|
// 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
|
// 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.
|
// worry about this being a native vs green mutex.
|
||||||
static LOCK: StaticMutex = StaticMutex::new();
|
static LOCK: Mutex = Mutex::new();
|
||||||
let _g = LOCK.lock();
|
unsafe {
|
||||||
|
LOCK.lock();
|
||||||
|
|
||||||
writeln!(w, "stack backtrace:")?;
|
writeln!(w, "stack backtrace:")?;
|
||||||
|
|
||||||
let mut cx = Context { writer: w, last_error: None, idx: 0 };
|
let mut cx = Context { writer: w, last_error: None, idx: 0 };
|
||||||
return match unsafe {
|
let ret = match {
|
||||||
uw::_Unwind_Backtrace(trace_fn,
|
uw::_Unwind_Backtrace(trace_fn,
|
||||||
&mut cx as *mut Context as *mut libc::c_void)
|
&mut cx as *mut Context as *mut libc::c_void)
|
||||||
} {
|
} {
|
||||||
uw::_URC_NO_REASON => {
|
uw::_URC_NO_REASON => {
|
||||||
match cx.last_error {
|
match cx.last_error {
|
||||||
Some(err) => Err(err),
|
Some(err) => Err(err),
|
||||||
None => Ok(())
|
None => Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
_ => Ok(()),
|
||||||
_ => Ok(()),
|
};
|
||||||
};
|
LOCK.unlock();
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
|
extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
|
||||||
arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
|
arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
|
||||||
|
|
|
@ -88,9 +88,7 @@ pub trait OpenOptionsExt {
|
||||||
/// }
|
/// }
|
||||||
/// let file = options.open("foo.txt");
|
/// let file = options.open("foo.txt");
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "expand_open_options",
|
#[stable(feature = "open_options_ext", since = "1.10.0")]
|
||||||
reason = "recently added",
|
|
||||||
issue = "30014")]
|
|
||||||
fn custom_flags(&mut self, flags: i32) -> &mut Self;
|
fn custom_flags(&mut self, flags: i32) -> &mut Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// 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
|
//! Unix-specific networking functionality
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ enum AddressKind<'a> {
|
||||||
|
|
||||||
/// An address associated with a Unix socket.
|
/// An address associated with a Unix socket.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub struct SocketAddr {
|
pub struct SocketAddr {
|
||||||
addr: libc::sockaddr_un,
|
addr: libc::sockaddr_un,
|
||||||
len: libc::socklen_t,
|
len: libc::socklen_t,
|
||||||
|
@ -109,6 +111,7 @@ impl SocketAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true iff the address is unnamed.
|
/// Returns true iff the address is unnamed.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn is_unnamed(&self) -> bool {
|
pub fn is_unnamed(&self) -> bool {
|
||||||
if let AddressKind::Unnamed = self.address() {
|
if let AddressKind::Unnamed = self.address() {
|
||||||
true
|
true
|
||||||
|
@ -118,6 +121,7 @@ impl SocketAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the contents of this address if it is a `pathname` address.
|
/// 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> {
|
pub fn as_pathname(&self) -> Option<&Path> {
|
||||||
if let AddressKind::Pathname(path) = self.address() {
|
if let AddressKind::Pathname(path) = self.address() {
|
||||||
Some(path)
|
Some(path)
|
||||||
|
@ -141,6 +145,7 @@ impl SocketAddr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl fmt::Debug for SocketAddr {
|
impl fmt::Debug for SocketAddr {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self.address() {
|
match self.address() {
|
||||||
|
@ -168,8 +173,6 @@ impl<'a> fmt::Display for AsciiEscaped<'a> {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// #![feature(unix_socket)]
|
|
||||||
///
|
|
||||||
/// use std::os::unix::net::UnixStream;
|
/// use std::os::unix::net::UnixStream;
|
||||||
/// use std::io::prelude::*;
|
/// use std::io::prelude::*;
|
||||||
///
|
///
|
||||||
|
@ -179,8 +182,10 @@ impl<'a> fmt::Display for AsciiEscaped<'a> {
|
||||||
/// stream.read_to_string(&mut response).unwrap();
|
/// stream.read_to_string(&mut response).unwrap();
|
||||||
/// println!("{}", response);
|
/// println!("{}", response);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub struct UnixStream(Socket);
|
pub struct UnixStream(Socket);
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl fmt::Debug for UnixStream {
|
impl fmt::Debug for UnixStream {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut builder = fmt.debug_struct("UnixStream");
|
let mut builder = fmt.debug_struct("UnixStream");
|
||||||
|
@ -197,6 +202,7 @@ impl fmt::Debug for UnixStream {
|
||||||
|
|
||||||
impl UnixStream {
|
impl UnixStream {
|
||||||
/// Connects to the socket named by `path`.
|
/// 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> {
|
pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
|
||||||
fn inner(path: &Path) -> io::Result<UnixStream> {
|
fn inner(path: &Path) -> io::Result<UnixStream> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -213,6 +219,7 @@ impl UnixStream {
|
||||||
/// Creates an unnamed pair of connected sockets.
|
/// Creates an unnamed pair of connected sockets.
|
||||||
///
|
///
|
||||||
/// Returns two `UnixStream`s which are connected to each other.
|
/// 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)> {
|
pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
|
||||||
let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
|
let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
|
||||||
Ok((UnixStream(i1), UnixStream(i2)))
|
Ok((UnixStream(i1), UnixStream(i2)))
|
||||||
|
@ -224,16 +231,19 @@ impl UnixStream {
|
||||||
/// object references. Both handles will read and write the same stream of
|
/// 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
|
/// data, and options set on one stream will be propogated to the other
|
||||||
/// stream.
|
/// stream.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn try_clone(&self) -> io::Result<UnixStream> {
|
pub fn try_clone(&self) -> io::Result<UnixStream> {
|
||||||
self.0.duplicate().map(UnixStream)
|
self.0.duplicate().map(UnixStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the socket address of the local half of this connection.
|
/// 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> {
|
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||||
SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
|
SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the socket address of the remote half of this connection.
|
/// 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> {
|
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||||
SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
|
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
|
/// If the provided value is `None`, then `read` calls will block
|
||||||
/// indefinitely. It is an error to pass the zero `Duration` to this
|
/// indefinitely. It is an error to pass the zero `Duration` to this
|
||||||
/// method.
|
/// method.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||||
self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
|
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
|
/// If the provided value is `None`, then `write` calls will block
|
||||||
/// indefinitely. It is an error to pass the zero `Duration` to this
|
/// indefinitely. It is an error to pass the zero `Duration` to this
|
||||||
/// method.
|
/// method.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||||
self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
|
self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the read timeout of this socket.
|
/// Returns the read timeout of this socket.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||||
self.0.timeout(libc::SO_RCVTIMEO)
|
self.0.timeout(libc::SO_RCVTIMEO)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the write timeout of this socket.
|
/// Returns the write timeout of this socket.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||||
self.0.timeout(libc::SO_SNDTIMEO)
|
self.0.timeout(libc::SO_SNDTIMEO)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves the socket into or out of nonblocking mode.
|
/// 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<()> {
|
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||||
self.0.set_nonblocking(nonblocking)
|
self.0.set_nonblocking(nonblocking)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the value of the `SO_ERROR` option.
|
/// 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>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
self.0.take_error()
|
self.0.take_error()
|
||||||
}
|
}
|
||||||
|
@ -281,11 +297,13 @@ impl UnixStream {
|
||||||
/// This function will cause all pending and future I/O calls on the
|
/// This function will cause all pending and future I/O calls on the
|
||||||
/// specified portions to immediately return with an appropriate value
|
/// specified portions to immediately return with an appropriate value
|
||||||
/// (see the documentation of `Shutdown`).
|
/// (see the documentation of `Shutdown`).
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||||
self.0.shutdown(how)
|
self.0.shutdown(how)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl io::Read for UnixStream {
|
impl io::Read for UnixStream {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
io::Read::read(&mut &*self, buf)
|
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 {
|
impl<'a> io::Read for &'a UnixStream {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.0.read(buf)
|
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 {
|
impl io::Write for UnixStream {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
io::Write::write(&mut &*self, buf)
|
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 {
|
impl<'a> io::Write for &'a UnixStream {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.write(buf)
|
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 {
|
impl AsRawFd for UnixStream {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
*self.0.as_inner()
|
*self.0.as_inner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl FromRawFd for UnixStream {
|
impl FromRawFd for UnixStream {
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
|
unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
|
||||||
UnixStream(Socket::from_inner(fd))
|
UnixStream(Socket::from_inner(fd))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl IntoRawFd for UnixStream {
|
impl IntoRawFd for UnixStream {
|
||||||
fn into_raw_fd(self) -> RawFd {
|
fn into_raw_fd(self) -> RawFd {
|
||||||
self.0.into_inner()
|
self.0.into_inner()
|
||||||
|
@ -349,8 +373,6 @@ impl IntoRawFd for UnixStream {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// #![feature(unix_socket)]
|
|
||||||
///
|
|
||||||
/// use std::thread;
|
/// use std::thread;
|
||||||
/// use std::os::unix::net::{UnixStream, UnixListener};
|
/// use std::os::unix::net::{UnixStream, UnixListener};
|
||||||
///
|
///
|
||||||
|
@ -377,8 +399,10 @@ impl IntoRawFd for UnixStream {
|
||||||
/// // close the listener socket
|
/// // close the listener socket
|
||||||
/// drop(listener);
|
/// drop(listener);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub struct UnixListener(Socket);
|
pub struct UnixListener(Socket);
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl fmt::Debug for UnixListener {
|
impl fmt::Debug for UnixListener {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut builder = fmt.debug_struct("UnixListener");
|
let mut builder = fmt.debug_struct("UnixListener");
|
||||||
|
@ -392,6 +416,7 @@ impl fmt::Debug for UnixListener {
|
||||||
|
|
||||||
impl UnixListener {
|
impl UnixListener {
|
||||||
/// Creates a new `UnixListener` bound to the specified socket.
|
/// 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> {
|
pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
|
||||||
fn inner(path: &Path) -> io::Result<UnixListener> {
|
fn inner(path: &Path) -> io::Result<UnixListener> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -412,6 +437,7 @@ impl UnixListener {
|
||||||
/// This function will block the calling thread until a new Unix connection
|
/// This function will block the calling thread until a new Unix connection
|
||||||
/// is established. When established, the corersponding `UnixStream` and
|
/// is established. When established, the corersponding `UnixStream` and
|
||||||
/// the remote peer's address will be returned.
|
/// the remote peer's address will be returned.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
|
pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
|
||||||
let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
|
let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
|
||||||
let mut len = mem::size_of_val(&storage) as libc::socklen_t;
|
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
|
/// The returned `UnixListener` is a reference to the same socket that this
|
||||||
/// object references. Both handles can be used to accept incoming
|
/// object references. Both handles can be used to accept incoming
|
||||||
/// connections and options set on one listener will affect the other.
|
/// 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> {
|
pub fn try_clone(&self) -> io::Result<UnixListener> {
|
||||||
self.0.duplicate().map(UnixListener)
|
self.0.duplicate().map(UnixListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the local socket address of this listener.
|
/// Returns the local socket address of this listener.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||||
SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
|
SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves the socket into or out of nonblocking mode.
|
/// 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<()> {
|
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||||
self.0.set_nonblocking(nonblocking)
|
self.0.set_nonblocking(nonblocking)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the value of the `SO_ERROR` option.
|
/// 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>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
self.0.take_error()
|
self.0.take_error()
|
||||||
}
|
}
|
||||||
|
@ -448,29 +478,34 @@ impl UnixListener {
|
||||||
///
|
///
|
||||||
/// The iterator will never return `None` and will also not yield the
|
/// The iterator will never return `None` and will also not yield the
|
||||||
/// peer's `SocketAddr` structure.
|
/// peer's `SocketAddr` structure.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn incoming<'a>(&'a self) -> Incoming<'a> {
|
pub fn incoming<'a>(&'a self) -> Incoming<'a> {
|
||||||
Incoming { listener: self }
|
Incoming { listener: self }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl AsRawFd for UnixListener {
|
impl AsRawFd for UnixListener {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
*self.0.as_inner()
|
*self.0.as_inner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl FromRawFd for UnixListener {
|
impl FromRawFd for UnixListener {
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
|
unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
|
||||||
UnixListener(Socket::from_inner(fd))
|
UnixListener(Socket::from_inner(fd))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl IntoRawFd for UnixListener {
|
impl IntoRawFd for UnixListener {
|
||||||
fn into_raw_fd(self) -> RawFd {
|
fn into_raw_fd(self) -> RawFd {
|
||||||
self.0.into_inner()
|
self.0.into_inner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl<'a> IntoIterator for &'a UnixListener {
|
impl<'a> IntoIterator for &'a UnixListener {
|
||||||
type Item = io::Result<UnixStream>;
|
type Item = io::Result<UnixStream>;
|
||||||
type IntoIter = Incoming<'a>;
|
type IntoIter = Incoming<'a>;
|
||||||
|
@ -484,10 +519,12 @@ impl<'a> IntoIterator for &'a UnixListener {
|
||||||
///
|
///
|
||||||
/// It will never return `None`.
|
/// It will never return `None`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub struct Incoming<'a> {
|
pub struct Incoming<'a> {
|
||||||
listener: &'a UnixListener,
|
listener: &'a UnixListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl<'a> Iterator for Incoming<'a> {
|
impl<'a> Iterator for Incoming<'a> {
|
||||||
type Item = io::Result<UnixStream>;
|
type Item = io::Result<UnixStream>;
|
||||||
|
|
||||||
|
@ -505,8 +542,6 @@ impl<'a> Iterator for Incoming<'a> {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// #![feature(unix_socket)]
|
|
||||||
///
|
|
||||||
/// use std::os::unix::net::UnixDatagram;
|
/// use std::os::unix::net::UnixDatagram;
|
||||||
///
|
///
|
||||||
/// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
|
/// 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();
|
/// let (count, address) = socket.recv_from(&mut buf).unwrap();
|
||||||
/// println!("socket {:?} sent {:?}", address, &buf[..count]);
|
/// println!("socket {:?} sent {:?}", address, &buf[..count]);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub struct UnixDatagram(Socket);
|
pub struct UnixDatagram(Socket);
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl fmt::Debug for UnixDatagram {
|
impl fmt::Debug for UnixDatagram {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut builder = fmt.debug_struct("UnixDatagram");
|
let mut builder = fmt.debug_struct("UnixDatagram");
|
||||||
|
@ -533,6 +570,7 @@ impl fmt::Debug for UnixDatagram {
|
||||||
|
|
||||||
impl UnixDatagram {
|
impl UnixDatagram {
|
||||||
/// Creates a Unix datagram socket bound to the given path.
|
/// 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> {
|
pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
|
||||||
fn inner(path: &Path) -> io::Result<UnixDatagram> {
|
fn inner(path: &Path) -> io::Result<UnixDatagram> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -548,6 +586,7 @@ impl UnixDatagram {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a Unix Datagram socket which is not bound to any address.
|
/// 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> {
|
pub fn unbound() -> io::Result<UnixDatagram> {
|
||||||
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
|
let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
|
||||||
Ok(UnixDatagram(inner))
|
Ok(UnixDatagram(inner))
|
||||||
|
@ -556,6 +595,7 @@ impl UnixDatagram {
|
||||||
/// Create an unnamed pair of connected sockets.
|
/// Create an unnamed pair of connected sockets.
|
||||||
///
|
///
|
||||||
/// Returns two `UnixDatagrams`s which are connected to each other.
|
/// 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)> {
|
pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
|
||||||
let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
|
let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
|
||||||
Ok((UnixDatagram(i1), UnixDatagram(i2)))
|
Ok((UnixDatagram(i1), UnixDatagram(i2)))
|
||||||
|
@ -565,6 +605,7 @@ impl UnixDatagram {
|
||||||
///
|
///
|
||||||
/// The `send` method may be used to send data to the specified address.
|
/// The `send` method may be used to send data to the specified address.
|
||||||
/// `recv` and `recv_from` will only receive data from that 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<()> {
|
pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
||||||
fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
|
fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -583,11 +624,13 @@ impl UnixDatagram {
|
||||||
/// The returned `UnixListener` is a reference to the same socket that this
|
/// The returned `UnixListener` is a reference to the same socket that this
|
||||||
/// object references. Both handles can be used to accept incoming
|
/// object references. Both handles can be used to accept incoming
|
||||||
/// connections and options set on one listener will affect the other.
|
/// 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> {
|
pub fn try_clone(&self) -> io::Result<UnixDatagram> {
|
||||||
self.0.duplicate().map(UnixDatagram)
|
self.0.duplicate().map(UnixDatagram)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the address of this socket.
|
/// Returns the address of this socket.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||||
SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
|
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.
|
/// Returns the address of this socket's peer.
|
||||||
///
|
///
|
||||||
/// The `connect` method will connect the socket to a 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> {
|
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||||
SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
|
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
|
/// On success, returns the number of bytes read and the address from
|
||||||
/// whence the data came.
|
/// whence the data came.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let addr = SocketAddr::new(|addr, len| {
|
let addr = SocketAddr::new(|addr, len| {
|
||||||
|
@ -629,6 +674,7 @@ impl UnixDatagram {
|
||||||
/// Receives data from the socket.
|
/// Receives data from the socket.
|
||||||
///
|
///
|
||||||
/// On success, returns the number of bytes read.
|
/// 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> {
|
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.0.read(buf)
|
self.0.read(buf)
|
||||||
}
|
}
|
||||||
|
@ -636,6 +682,7 @@ impl UnixDatagram {
|
||||||
/// Sends data on the socket to the specified address.
|
/// Sends data on the socket to the specified address.
|
||||||
///
|
///
|
||||||
/// On success, returns the number of bytes written.
|
/// 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> {
|
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> {
|
fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -659,6 +706,7 @@ impl UnixDatagram {
|
||||||
/// will return an error if the socket has not already been connected.
|
/// will return an error if the socket has not already been connected.
|
||||||
///
|
///
|
||||||
/// On success, returns the number of bytes written.
|
/// 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> {
|
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.write(buf)
|
self.0.write(buf)
|
||||||
}
|
}
|
||||||
|
@ -668,6 +716,7 @@ impl UnixDatagram {
|
||||||
/// If the provided value is `None`, then `recv` and `recv_from` calls will
|
/// 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
|
/// block indefinitely. It is an error to pass the zero `Duration` to this
|
||||||
/// method.
|
/// method.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||||
self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
|
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
|
/// 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
|
/// block indefinitely. It is an error to pass the zero `Duration` to this
|
||||||
/// method.
|
/// method.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||||
self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
|
self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the read timeout of this socket.
|
/// Returns the read timeout of this socket.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||||
self.0.timeout(libc::SO_RCVTIMEO)
|
self.0.timeout(libc::SO_RCVTIMEO)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the write timeout of this socket.
|
/// Returns the write timeout of this socket.
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||||
self.0.timeout(libc::SO_SNDTIMEO)
|
self.0.timeout(libc::SO_SNDTIMEO)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves the socket into or out of nonblocking mode.
|
/// 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<()> {
|
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||||
self.0.set_nonblocking(nonblocking)
|
self.0.set_nonblocking(nonblocking)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the value of the `SO_ERROR` option.
|
/// 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>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
self.0.take_error()
|
self.0.take_error()
|
||||||
}
|
}
|
||||||
|
@ -706,23 +760,27 @@ impl UnixDatagram {
|
||||||
/// This function will cause all pending and future I/O calls on the
|
/// This function will cause all pending and future I/O calls on the
|
||||||
/// specified portions to immediately return with an appropriate value
|
/// specified portions to immediately return with an appropriate value
|
||||||
/// (see the documentation of `Shutdown`).
|
/// (see the documentation of `Shutdown`).
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||||
self.0.shutdown(how)
|
self.0.shutdown(how)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl AsRawFd for UnixDatagram {
|
impl AsRawFd for UnixDatagram {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
*self.0.as_inner()
|
*self.0.as_inner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl FromRawFd for UnixDatagram {
|
impl FromRawFd for UnixDatagram {
|
||||||
unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
|
unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
|
||||||
UnixDatagram(Socket::from_inner(fd))
|
UnixDatagram(Socket::from_inner(fd))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "unix_socket", since = "1.10.0")]
|
||||||
impl IntoRawFd for UnixDatagram {
|
impl IntoRawFd for UnixDatagram {
|
||||||
fn into_raw_fd(self) -> RawFd {
|
fn into_raw_fd(self) -> RawFd {
|
||||||
self.0.into_inner()
|
self.0.into_inner()
|
||||||
|
|
|
@ -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")]
|
#[cfg(target_os = "netbsd")]
|
||||||
impl FileAttr {
|
impl FileAttr {
|
||||||
pub fn modified(&self) -> io::Result<SystemTime> {
|
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 {
|
impl FileAttr {
|
||||||
pub fn modified(&self) -> io::Result<SystemTime> {
|
pub fn modified(&self) -> io::Result<SystemTime> {
|
||||||
Ok(SystemTime::from(libc::timespec {
|
Ok(SystemTime::from(libc::timespec {
|
||||||
|
@ -167,7 +142,9 @@ impl FileAttr {
|
||||||
|
|
||||||
#[cfg(any(target_os = "bitrig",
|
#[cfg(any(target_os = "bitrig",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "openbsd"))]
|
target_os = "openbsd",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "ios"))]
|
||||||
pub fn created(&self) -> io::Result<SystemTime> {
|
pub fn created(&self) -> io::Result<SystemTime> {
|
||||||
Ok(SystemTime::from(libc::timespec {
|
Ok(SystemTime::from(libc::timespec {
|
||||||
tv_sec: self.stat.st_birthtime as libc::time_t,
|
tv_sec: self.stat.st_birthtime as libc::time_t,
|
||||||
|
@ -177,7 +154,9 @@ impl FileAttr {
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "bitrig",
|
#[cfg(not(any(target_os = "bitrig",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "openbsd")))]
|
target_os = "openbsd",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "ios")))]
|
||||||
pub fn created(&self) -> io::Result<SystemTime> {
|
pub fn created(&self) -> io::Result<SystemTime> {
|
||||||
Err(io::Error::new(io::ErrorKind::Other,
|
Err(io::Error::new(io::ErrorKind::Other,
|
||||||
"creation time is not available on this platform \
|
"creation time is not available on this platform \
|
||||||
|
|
|
@ -27,13 +27,13 @@ use path::{self, PathBuf};
|
||||||
use ptr;
|
use ptr;
|
||||||
use slice;
|
use slice;
|
||||||
use str;
|
use str;
|
||||||
use sync::StaticMutex;
|
use sys_common::mutex::Mutex;
|
||||||
use sys::cvt;
|
use sys::cvt;
|
||||||
use sys::fd;
|
use sys::fd;
|
||||||
use vec;
|
use vec;
|
||||||
|
|
||||||
const TMPBUF_SZ: usize = 128;
|
const TMPBUF_SZ: usize = 128;
|
||||||
static ENV_LOCK: StaticMutex = StaticMutex::new();
|
static ENV_LOCK: Mutex = Mutex::new();
|
||||||
|
|
||||||
/// Returns the platform-specific value of errno
|
/// Returns the platform-specific value of errno
|
||||||
#[cfg(not(target_os = "dragonfly"))]
|
#[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
|
/// Returns a vector of (variable, value) byte-vector pairs for all the
|
||||||
/// environment variables of the current process.
|
/// environment variables of the current process.
|
||||||
pub fn env() -> Env {
|
pub fn env() -> Env {
|
||||||
let _g = ENV_LOCK.lock();
|
unsafe {
|
||||||
return unsafe {
|
ENV_LOCK.lock();
|
||||||
let mut environ = *environ();
|
let mut environ = *environ();
|
||||||
if environ == ptr::null() {
|
if environ == ptr::null() {
|
||||||
|
ENV_LOCK.unlock();
|
||||||
panic!("os::env() failure getting env string from OS: {}",
|
panic!("os::env() failure getting env string from OS: {}",
|
||||||
io::Error::last_os_error());
|
io::Error::last_os_error());
|
||||||
}
|
}
|
||||||
|
@ -448,8 +449,13 @@ pub fn env() -> Env {
|
||||||
}
|
}
|
||||||
environ = environ.offset(1);
|
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)> {
|
fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
|
||||||
// Strategy (copied from glibc): Variable name and value are separated
|
// 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
|
// environment variables with a nul byte can't be set, so their value is
|
||||||
// always None as well
|
// always None as well
|
||||||
let k = CString::new(k.as_bytes())?;
|
let k = CString::new(k.as_bytes())?;
|
||||||
let _g = ENV_LOCK.lock();
|
unsafe {
|
||||||
Ok(unsafe {
|
ENV_LOCK.lock();
|
||||||
let s = libc::getenv(k.as_ptr()) as *const _;
|
let s = libc::getenv(k.as_ptr()) as *const _;
|
||||||
if s.is_null() {
|
let ret = if s.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
|
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<()> {
|
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
|
||||||
let k = CString::new(k.as_bytes())?;
|
let k = CString::new(k.as_bytes())?;
|
||||||
let v = CString::new(v.as_bytes())?;
|
let v = CString::new(v.as_bytes())?;
|
||||||
let _g = ENV_LOCK.lock();
|
|
||||||
cvt(unsafe {
|
unsafe {
|
||||||
libc::setenv(k.as_ptr(), v.as_ptr(), 1)
|
ENV_LOCK.lock();
|
||||||
}).map(|_| ())
|
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<()> {
|
pub fn unsetenv(n: &OsStr) -> io::Result<()> {
|
||||||
let nbuf = CString::new(n.as_bytes())?;
|
let nbuf = CString::new(n.as_bytes())?;
|
||||||
let _g = ENV_LOCK.lock();
|
|
||||||
cvt(unsafe {
|
unsafe {
|
||||||
libc::unsetenv(nbuf.as_ptr())
|
ENV_LOCK.lock();
|
||||||
}).map(|_| ())
|
let ret = cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ());
|
||||||
|
ENV_LOCK.unlock();
|
||||||
|
return ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_size() -> usize {
|
pub fn page_size() -> usize {
|
||||||
|
|
|
@ -8,37 +8,129 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use cmp::Ordering;
|
||||||
|
use time::Duration;
|
||||||
|
use libc;
|
||||||
|
|
||||||
pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
|
pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
const NSEC_PER_SEC: u64 = 1_000_000_000;
|
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"))]
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||||
mod inner {
|
mod inner {
|
||||||
use cmp::Ordering;
|
|
||||||
use fmt;
|
use fmt;
|
||||||
use libc;
|
use libc;
|
||||||
use super::NSEC_PER_SEC;
|
|
||||||
use sync::Once;
|
use sync::Once;
|
||||||
use sys::cvt;
|
use sys::cvt;
|
||||||
use sys_common::mul_div_u64;
|
use sys_common::mul_div_u64;
|
||||||
use time::Duration;
|
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)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||||
pub struct Instant {
|
pub struct Instant {
|
||||||
t: u64
|
t: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct SystemTime {
|
pub struct SystemTime {
|
||||||
t: libc::timeval,
|
t: Timespec,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const UNIX_EPOCH: SystemTime = SystemTime {
|
pub const UNIX_EPOCH: SystemTime = SystemTime {
|
||||||
t: libc::timeval {
|
t: Timespec {
|
||||||
tv_sec: 0,
|
t: libc::timespec {
|
||||||
tv_usec: 0,
|
tv_sec: 0,
|
||||||
|
tv_nsec: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,113 +164,50 @@ mod inner {
|
||||||
|
|
||||||
impl SystemTime {
|
impl SystemTime {
|
||||||
pub fn now() -> SystemTime {
|
pub fn now() -> SystemTime {
|
||||||
let mut s = SystemTime {
|
let mut s = libc::timeval {
|
||||||
t: libc::timeval {
|
tv_sec: 0,
|
||||||
tv_sec: 0,
|
tv_usec: 0,
|
||||||
tv_usec: 0,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
cvt(unsafe {
|
cvt(unsafe {
|
||||||
libc::gettimeofday(&mut s.t, 0 as *mut _)
|
libc::gettimeofday(&mut s, 0 as *mut _)
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
return s
|
return SystemTime::from(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub_time(&self, other: &SystemTime)
|
pub fn sub_time(&self, other: &SystemTime)
|
||||||
-> Result<Duration, Duration> {
|
-> Result<Duration, Duration> {
|
||||||
if self >= other {
|
self.t.sub_timespec(&other.t)
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_duration(&self, other: &Duration) -> SystemTime {
|
pub fn add_duration(&self, other: &Duration) -> SystemTime {
|
||||||
let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
|
SystemTime { t: self.t.add_duration(other) }
|
||||||
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,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub_duration(&self, other: &Duration) -> SystemTime {
|
pub fn sub_duration(&self, other: &Duration) -> SystemTime {
|
||||||
let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
|
SystemTime { t: self.t.sub_duration(other) }
|
||||||
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,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<libc::timeval> for SystemTime {
|
impl From<libc::timeval> for SystemTime {
|
||||||
fn from(t: libc::timeval) -> SystemTime {
|
fn from(t: libc::timeval) -> SystemTime {
|
||||||
SystemTime { t: t }
|
SystemTime::from(libc::timespec {
|
||||||
|
tv_sec: t.tv_sec,
|
||||||
|
tv_nsec: (t.tv_usec * 1000) as libc::c_long,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for SystemTime {
|
impl From<libc::timespec> for SystemTime {
|
||||||
fn eq(&self, other: &SystemTime) -> bool {
|
fn from(t: libc::timespec) -> SystemTime {
|
||||||
self.t.tv_sec == other.t.tv_sec && self.t.tv_usec == other.t.tv_usec
|
SystemTime { t: Timespec { t: t } }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for SystemTime {}
|
|
||||||
|
|
||||||
impl PartialOrd for SystemTime {
|
|
||||||
fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 fmt::Debug for SystemTime {
|
impl fmt::Debug for SystemTime {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("SystemTime")
|
f.debug_struct("SystemTime")
|
||||||
.field("tv_sec", &self.t.tv_sec)
|
.field("tv_sec", &self.t.t.tv_sec)
|
||||||
.field("tv_usec", &self.t.tv_usec)
|
.field("tv_nsec", &self.t.t.tv_nsec)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,17 +238,12 @@ mod inner {
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
|
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
|
||||||
mod inner {
|
mod inner {
|
||||||
use cmp::Ordering;
|
|
||||||
use fmt;
|
use fmt;
|
||||||
use libc;
|
use libc;
|
||||||
use super::NSEC_PER_SEC;
|
|
||||||
use sys::cvt;
|
use sys::cvt;
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
use super::Timespec;
|
||||||
struct Timespec {
|
|
||||||
t: libc::timespec,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Instant {
|
pub struct Instant {
|
||||||
|
@ -242,7 +266,7 @@ mod inner {
|
||||||
|
|
||||||
impl Instant {
|
impl Instant {
|
||||||
pub fn now() -> 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 {
|
pub fn sub_instant(&self, other: &Instant) -> Duration {
|
||||||
|
@ -271,7 +295,7 @@ mod inner {
|
||||||
|
|
||||||
impl SystemTime {
|
impl SystemTime {
|
||||||
pub fn now() -> 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)
|
pub fn sub_time(&self, other: &SystemTime)
|
||||||
|
@ -308,98 +332,16 @@ mod inner {
|
||||||
#[cfg(target_os = "dragonfly")]
|
#[cfg(target_os = "dragonfly")]
|
||||||
pub type clock_t = libc::c_ulong;
|
pub type clock_t = libc::c_ulong;
|
||||||
|
|
||||||
impl Timespec {
|
fn now(clock: clock_t) -> Timespec {
|
||||||
pub fn now(clock: clock_t) -> Timespec {
|
let mut t = Timespec {
|
||||||
let mut t = Timespec {
|
t: libc::timespec {
|
||||||
t: libc::timespec {
|
tv_sec: 0,
|
||||||
tv_sec: 0,
|
tv_nsec: 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),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
cvt(unsafe {
|
||||||
fn add_duration(&self, other: &Duration) -> Timespec {
|
libc::clock_gettime(clock, &mut t.t)
|
||||||
let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
|
}).unwrap();
|
||||||
let mut secs = secs.expect("overflow when adding duration to time");
|
t
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,7 @@ use sys;
|
||||||
use sys_common::{AsInnerMut, AsInner};
|
use sys_common::{AsInnerMut, AsInner};
|
||||||
|
|
||||||
/// Windows-specific extensions to `OpenOptions`
|
/// Windows-specific extensions to `OpenOptions`
|
||||||
#[unstable(feature = "open_options_ext",
|
#[stable(feature = "open_options_ext", since = "1.10.0")]
|
||||||
reason = "may require more thought/methods",
|
|
||||||
issue = "27720")]
|
|
||||||
pub trait OpenOptionsExt {
|
pub trait OpenOptionsExt {
|
||||||
/// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
|
/// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
|
||||||
/// with the specified value.
|
/// with the specified value.
|
||||||
|
@ -34,7 +32,6 @@ pub trait OpenOptionsExt {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(open_options_ext)]
|
|
||||||
/// use std::fs::OpenOptions;
|
/// use std::fs::OpenOptions;
|
||||||
/// use std::os::windows::fs::OpenOptionsExt;
|
/// use std::os::windows::fs::OpenOptionsExt;
|
||||||
///
|
///
|
||||||
|
@ -42,6 +39,7 @@ pub trait OpenOptionsExt {
|
||||||
/// // to call `stat()` on the file
|
/// // to call `stat()` on the file
|
||||||
/// let file = OpenOptions::new().access_mode(0).open("foo.txt");
|
/// 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;
|
fn access_mode(&mut self, access: u32) -> &mut Self;
|
||||||
|
|
||||||
/// Overrides the `dwShareMode` argument to the call to `CreateFile` with
|
/// Overrides the `dwShareMode` argument to the call to `CreateFile` with
|
||||||
|
@ -55,7 +53,6 @@ pub trait OpenOptionsExt {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(open_options_ext)]
|
|
||||||
/// use std::fs::OpenOptions;
|
/// use std::fs::OpenOptions;
|
||||||
/// use std::os::windows::fs::OpenOptionsExt;
|
/// use std::os::windows::fs::OpenOptionsExt;
|
||||||
///
|
///
|
||||||
|
@ -65,6 +62,7 @@ pub trait OpenOptionsExt {
|
||||||
/// .share_mode(0)
|
/// .share_mode(0)
|
||||||
/// .open("foo.txt");
|
/// .open("foo.txt");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "open_options_ext", since = "1.10.0")]
|
||||||
fn share_mode(&mut self, val: u32) -> &mut Self;
|
fn share_mode(&mut self, val: u32) -> &mut Self;
|
||||||
|
|
||||||
/// Sets extra flags for the `dwFileFlags` argument to the call to
|
/// Sets extra flags for the `dwFileFlags` argument to the call to
|
||||||
|
@ -88,9 +86,7 @@ pub trait OpenOptionsExt {
|
||||||
/// }
|
/// }
|
||||||
/// let file = options.open("foo.txt");
|
/// let file = options.open("foo.txt");
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "expand_open_options",
|
#[stable(feature = "open_options_ext", since = "1.10.0")]
|
||||||
reason = "recently added",
|
|
||||||
issue = "30014")]
|
|
||||||
fn custom_flags(&mut self, flags: u32) -> &mut Self;
|
fn custom_flags(&mut self, flags: u32) -> &mut Self;
|
||||||
|
|
||||||
/// Sets the `dwFileAttributes` argument to the call to `CreateFile2` to
|
/// Sets the `dwFileAttributes` argument to the call to `CreateFile2` to
|
||||||
|
@ -111,7 +107,6 @@ pub trait OpenOptionsExt {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// #![feature(open_options_ext)]
|
|
||||||
/// extern crate winapi;
|
/// extern crate winapi;
|
||||||
/// use std::fs::OpenOptions;
|
/// use std::fs::OpenOptions;
|
||||||
/// use std::os::windows::fs::OpenOptionsExt;
|
/// use std::os::windows::fs::OpenOptionsExt;
|
||||||
|
@ -120,17 +115,17 @@ pub trait OpenOptionsExt {
|
||||||
/// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
|
/// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
|
||||||
/// .open("foo.txt");
|
/// .open("foo.txt");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[stable(feature = "open_options_ext", since = "1.10.0")]
|
||||||
fn attributes(&mut self, val: u32) -> &mut Self;
|
fn attributes(&mut self, val: u32) -> &mut Self;
|
||||||
|
|
||||||
/// Sets the `dwSecurityQosFlags` argument to the call to `CreateFile2` to
|
/// Sets the `dwSecurityQosFlags` argument to the call to `CreateFile2` to
|
||||||
/// the specified value (or combines it with `custom_flags` and `attributes`
|
/// the specified value (or combines it with `custom_flags` and `attributes`
|
||||||
/// to set the `dwFlagsAndAttributes` for `CreateFile`).
|
/// 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;
|
fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "open_options_ext",
|
#[stable(feature = "open_options_ext", since = "1.10.0")]
|
||||||
reason = "may require more thought/methods",
|
|
||||||
issue = "27720")]
|
|
||||||
impl OpenOptionsExt for OpenOptions {
|
impl OpenOptionsExt for OpenOptions {
|
||||||
fn access_mode(&mut self, access: u32) -> &mut OpenOptions {
|
fn access_mode(&mut self, access: u32) -> &mut OpenOptions {
|
||||||
self.as_inner_mut().access_mode(access); self
|
self.as_inner_mut().access_mode(access); self
|
||||||
|
|
|
@ -24,7 +24,7 @@ use mem;
|
||||||
use os::windows::ffi::OsStrExt;
|
use os::windows::ffi::OsStrExt;
|
||||||
use path::Path;
|
use path::Path;
|
||||||
use ptr;
|
use ptr;
|
||||||
use sync::StaticMutex;
|
use sys::mutex::Mutex;
|
||||||
use sys::c;
|
use sys::c;
|
||||||
use sys::fs::{OpenOptions, File};
|
use sys::fs::{OpenOptions, File};
|
||||||
use sys::handle::Handle;
|
use sys::handle::Handle;
|
||||||
|
@ -75,6 +75,10 @@ pub struct StdioPipes {
|
||||||
pub stderr: Option<AnonPipe>,
|
pub stderr: Option<AnonPipe>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DropGuard<'a> {
|
||||||
|
lock: &'a Mutex,
|
||||||
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn new(program: &OsStr) -> Command {
|
pub fn new(program: &OsStr) -> Command {
|
||||||
Command {
|
Command {
|
||||||
|
@ -173,8 +177,8 @@ impl Command {
|
||||||
//
|
//
|
||||||
// For more information, msdn also has an article about this race:
|
// For more information, msdn also has an article about this race:
|
||||||
// http://support.microsoft.com/kb/315939
|
// http://support.microsoft.com/kb/315939
|
||||||
static CREATE_PROCESS_LOCK: StaticMutex = StaticMutex::new();
|
static CREATE_PROCESS_LOCK: Mutex = Mutex::new();
|
||||||
let _lock = CREATE_PROCESS_LOCK.lock();
|
let _guard = DropGuard::new(&CREATE_PROCESS_LOCK);
|
||||||
|
|
||||||
let mut pipes = StdioPipes {
|
let mut pipes = StdioPipes {
|
||||||
stdin: None,
|
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 {
|
impl Stdio {
|
||||||
fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>)
|
fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>)
|
||||||
-> io::Result<Handle> {
|
-> io::Result<Handle> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue