diff options
| author | Giles Cope <gilescope@gmail.com> | 2017-06-19 23:00:45 +0100 |
|---|---|---|
| committer | Giles Cope <gilescope@gmail.com> | 2017-06-19 23:00:45 +0100 |
| commit | 4b8446a2333ca7a22a594a24e3eb541cf5265792 (patch) | |
| tree | 84ac480b1cb9c6172ec41fb17aa1e526e163ed38 /src/libstd/sys | |
| parent | 1ec1b1f1eb1bd0ea1f9396ade1015d00f9149a1d (diff) | |
| parent | 04145943a25c3b8c7e7d7fe8c2efb04f259c25fb (diff) | |
| download | rust-4b8446a2333ca7a22a594a24e3eb541cf5265792.tar.gz rust-4b8446a2333ca7a22a594a24e3eb541cf5265792.zip | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/redox/os_str.rs | 27 | ||||
| -rw-r--r-- | src/libstd/sys/unix/condvar.rs | 34 | ||||
| -rw-r--r-- | src/libstd/sys/unix/os_str.rs | 27 | ||||
| -rw-r--r-- | src/libstd/sys/unix/pipe.rs | 29 | ||||
| -rw-r--r-- | src/libstd/sys/windows/os_str.rs | 26 |
5 files changed, 112 insertions, 31 deletions
diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys/redox/os_str.rs index c2bba07f68c..c54286353a9 100644 --- a/src/libstd/sys/redox/os_str.rs +++ b/src/libstd/sys/redox/os_str.rs @@ -12,10 +12,11 @@ /// a `Vec<u8>`/`[u8]`. use borrow::Cow; -use fmt::{self, Debug}; +use fmt; use str; use mem; use sys_common::{AsInner, IntoInner}; +use std_unicode::lossy::Utf8Lossy; #[derive(Clone, Hash)] pub struct Buf { @@ -26,15 +27,27 @@ pub struct Slice { pub inner: [u8] } -impl Debug for Slice { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.to_string_lossy().fmt(formatter) +impl fmt::Debug for Slice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter) } } -impl Debug for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.as_slice().fmt(formatter) +impl fmt::Display for Slice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter) + } +} + +impl fmt::Debug for Buf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.as_slice(), formatter) + } +} + +impl fmt::Display for Buf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self.as_slice(), formatter) } } diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index 27b9f131d12..b9ea573b323 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -23,6 +23,14 @@ const TIMESPEC_MAX: libc::timespec = libc::timespec { tv_nsec: 1_000_000_000 - 1, }; +fn saturating_cast_to_time_t(value: u64) -> libc::time_t { + if value > <libc::time_t>::max_value() as u64 { + <libc::time_t>::max_value() + } else { + value as libc::time_t + } +} + impl Condvar { pub const fn new() -> Condvar { // Might be moved and address is changing it is better to avoid @@ -79,8 +87,7 @@ impl Condvar { // Nanosecond calculations can't overflow because both values are below 1e9. let nsec = dur.subsec_nanos() as libc::c_long + now.tv_nsec as libc::c_long; - // FIXME: Casting u64 into time_t could truncate the value. - let sec = (dur.as_secs() as libc::time_t) + let sec = saturating_cast_to_time_t(dur.as_secs()) .checked_add((nsec / 1_000_000_000) as libc::time_t) .and_then(|s| s.checked_add(now.tv_sec)); let nsec = nsec % 1_000_000_000; @@ -100,10 +107,29 @@ impl Condvar { // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46 // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367 #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))] - pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { + pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool { use ptr; use time::Instant; + // 1000 years + let max_dur = Duration::from_secs(1000 * 365 * 86400); + + if dur > max_dur { + // OSX implementation of `pthread_cond_timedwait` is buggy + // with super long durations. When duration is greater than + // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` + // in macOS Sierra return error 316. + // + // This program demonstrates the issue: + // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c + // + // To work around this issue, and possible bugs of other OSes, timeout + // is clamped to 1000 years, which is allowable per the API of `wait_timeout` + // because of spurious wakeups. + + dur = max_dur; + } + // First, figure out what time it currently is, in both system and // stable time. pthread_cond_timedwait uses system time, but we want to // report timeout based on stable time. @@ -116,7 +142,7 @@ impl Condvar { (sys_now.tv_usec * 1000) as libc::c_long; let extra = (nsec / 1_000_000_000) as libc::time_t; let nsec = nsec % 1_000_000_000; - let seconds = dur.as_secs() as libc::time_t; + let seconds = saturating_cast_to_time_t(dur.as_secs()); let timeout = sys_now.tv_sec.checked_add(extra).and_then(|s| { s.checked_add(seconds) diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs index f5b942d3343..777db17e3e1 100644 --- a/src/libstd/sys/unix/os_str.rs +++ b/src/libstd/sys/unix/os_str.rs @@ -12,10 +12,11 @@ /// a `Vec<u8>`/`[u8]`. use borrow::Cow; -use fmt::{self, Debug}; +use fmt; use str; use mem; use sys_common::{AsInner, IntoInner}; +use std_unicode::lossy::Utf8Lossy; #[derive(Clone, Hash)] pub struct Buf { @@ -26,15 +27,27 @@ pub struct Slice { pub inner: [u8] } -impl Debug for Slice { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.to_string_lossy().fmt(formatter) +impl fmt::Debug for Slice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter) } } -impl Debug for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.as_slice().fmt(formatter) +impl fmt::Display for Slice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter) + } +} + +impl fmt::Debug for Buf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.as_slice(), formatter) + } +} + +impl fmt::Display for Buf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self.as_slice(), formatter) } } diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 706256ff10e..ca5ef4bcfc5 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -11,8 +11,9 @@ use io; use libc::{self, c_int}; use mem; -use sys::{cvt, cvt_r}; +use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; use sys::fd::FileDesc; +use sys::{cvt, cvt_r}; //////////////////////////////////////////////////////////////////////////////// // Anonymous pipes @@ -21,6 +22,9 @@ use sys::fd::FileDesc; pub struct AnonPipe(FileDesc); pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { + weak! { fn pipe2(*mut c_int, c_int) -> c_int } + static INVALID: AtomicBool = ATOMIC_BOOL_INIT; + let mut fds = [0; 2]; // Unfortunately the only known way right now to create atomically set the @@ -31,13 +35,26 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { target_os = "freebsd", target_os = "linux", target_os = "netbsd", - target_os = "openbsd")) + target_os = "openbsd")) && + !INVALID.load(Ordering::SeqCst) { - weak! { fn pipe2(*mut c_int, c_int) -> c_int } + if let Some(pipe) = pipe2.get() { - cvt(unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) })?; - return Ok((AnonPipe(FileDesc::new(fds[0])), - AnonPipe(FileDesc::new(fds[1])))); + // Note that despite calling a glibc function here we may still + // get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to + // emulate on older kernels, so if you happen to be running on + // an older kernel you may see `pipe2` as a symbol but still not + // see the syscall. + match cvt(unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) }) { + Ok(_) => { + return Ok((AnonPipe(FileDesc::new(fds[0])), + AnonPipe(FileDesc::new(fds[1])))); + } + Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => { + INVALID.store(true, Ordering::SeqCst); + } + Err(e) => return Err(e), + } } } cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?; diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs index f401e7b35c8..3eb4582718b 100644 --- a/src/libstd/sys/windows/os_str.rs +++ b/src/libstd/sys/windows/os_str.rs @@ -12,7 +12,7 @@ /// wrapper around the "WTF-8" encoding; see the `wtf8` module for more. use borrow::Cow; -use fmt::{self, Debug}; +use fmt; use sys_common::wtf8::{Wtf8, Wtf8Buf}; use mem; use sys_common::{AsInner, IntoInner}; @@ -34,9 +34,15 @@ impl AsInner<Wtf8> for Buf { } } -impl Debug for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.as_slice().fmt(formatter) +impl fmt::Debug for Buf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.as_slice(), formatter) + } +} + +impl fmt::Display for Buf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self.as_slice(), formatter) } } @@ -44,9 +50,15 @@ pub struct Slice { pub inner: Wtf8 } -impl Debug for Slice { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.inner.fmt(formatter) +impl fmt::Debug for Slice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self.inner, formatter) + } +} + +impl fmt::Display for Slice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.inner, formatter) } } |
