diff options
| author | bors <bors@rust-lang.org> | 2014-03-12 15:07:06 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-03-12 15:07:06 -0700 |
| commit | 4d64441bcb820cf35d3e39dde8514c46765a12a6 (patch) | |
| tree | 541bf3eb9112d8e40475b90f6da342980bbde7f8 /src/libstd | |
| parent | 3316a0e6b2ad9352bab58e7c046ef3d212411d82 (diff) | |
| parent | 3f2434eee3f7fa72bf7a8693aef3932d563cf8d5 (diff) | |
| download | rust-4d64441bcb820cf35d3e39dde8514c46765a12a6.tar.gz rust-4d64441bcb820cf35d3e39dde8514c46765a12a6.zip | |
auto merge of #12848 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/comm/oneshot.rs | 19 | ||||
| -rw-r--r-- | src/libstd/comm/select.rs | 52 | ||||
| -rw-r--r-- | src/libstd/io/mod.rs | 34 | ||||
| -rw-r--r-- | src/libstd/io/test.rs | 1 | ||||
| -rw-r--r-- | src/libstd/libc.rs | 23 | ||||
| -rw-r--r-- | src/libstd/os.rs | 4 | ||||
| -rw-r--r-- | src/libstd/path/posix.rs | 8 | ||||
| -rw-r--r-- | src/libstd/path/windows.rs | 8 | ||||
| -rw-r--r-- | src/libstd/str.rs | 11 |
9 files changed, 113 insertions, 47 deletions
diff --git a/src/libstd/comm/oneshot.rs b/src/libstd/comm/oneshot.rs index 9deccfeb875..0f78c1971bc 100644 --- a/src/libstd/comm/oneshot.rs +++ b/src/libstd/comm/oneshot.rs @@ -339,14 +339,19 @@ impl<T: Send> Packet<T> { DATA => Ok(true), // If the other end has hung up, then we have complete ownership - // of the port. We need to check to see if there was an upgrade - // requested, and if so, the other end needs to have its selection - // aborted. + // of the port. First, check if there was data waiting for us. This + // is possible if the other end sent something and then hung up. + // + // We then need to check to see if there was an upgrade requested, + // and if so, the upgraded port needs to have its selection aborted. DISCONNECTED => { - assert!(self.data.is_none()); - match mem::replace(&mut self.upgrade, SendUsed) { - GoUp(port) => Err(port), - _ => Ok(true), + if self.data.is_some() { + Ok(true) + } else { + match mem::replace(&mut self.upgrade, SendUsed) { + GoUp(port) => Err(port), + _ => Ok(true), + } } } diff --git a/src/libstd/comm/select.rs b/src/libstd/comm/select.rs index 75e7265705a..3c6828fc14f 100644 --- a/src/libstd/comm/select.rs +++ b/src/libstd/comm/select.rs @@ -597,4 +597,56 @@ mod test { unsafe { h.add(); } assert_eq!(s.wait2(false), h.id); }) + + test!(fn oneshot_data_waiting() { + let (p, c) = Chan::new(); + let (p2, c2) = Chan::new(); + spawn(proc() { + select! { + () = p.recv() => {} + } + c2.send(()); + }); + + for _ in range(0, 100) { task::deschedule() } + c.send(()); + p2.recv(); + }) + + test!(fn stream_data_waiting() { + let (p, c) = Chan::new(); + let (p2, c2) = Chan::new(); + c.send(()); + c.send(()); + p.recv(); + p.recv(); + spawn(proc() { + select! { + () = p.recv() => {} + } + c2.send(()); + }); + + for _ in range(0, 100) { task::deschedule() } + c.send(()); + p2.recv(); + }) + + test!(fn shared_data_waiting() { + let (p, c) = Chan::new(); + let (p2, c2) = Chan::new(); + drop(c.clone()); + c.send(()); + p.recv(); + spawn(proc() { + select! { + () = p.recv() => {} + } + c2.send(()); + }); + + for _ in range(0, 100) { task::deschedule() } + c.send(()); + p2.recv(); + }) } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 7a18f24140a..1c10c7b61c3 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -172,6 +172,40 @@ need to inspect or unwrap the `IoResult<File>` and we simply call `write_line` on it. If `new` returned an `Err(..)` then the followup call to `write_line` will also return an error. +## `try!` + +Explicit pattern matching on `IoResult`s can get quite verbose, especially +when performing many I/O operations. Some examples (like those above) are +alleviated with extra methods implemented on `IoResult`, but others have more +complex interdependencies among each I/O operation. + +The `try!` macro from `std::macros` is provided as a method of early-return +inside `Result`-returning functions. It expands to an early-return on `Err` +and otherwise unwraps the contained `Ok` value. + +If you wanted to read several `u32`s from a file and return their product: + +```rust +use std::io::{File, IoResult}; + +fn file_product(p: &Path) -> IoResult<u32> { + let mut f = File::open(p); + let x1 = try!(f.read_le_u32()); + let x2 = try!(f.read_le_u32()); + + Ok(x1 * x2) +} + +match file_product(&Path::new("numbers.bin")) { + Ok(x) => println!("{}", x), + Err(e) => println!("Failed to read numbers!") +} +``` + +With `try!` in `file_product`, each `read_le_u32` need not be directly +concerned with error handling; instead its caller is responsible for +responding to errors that may occur while attempting to read the numbers. + */ #[deny(unused_must_use)]; diff --git a/src/libstd/io/test.rs b/src/libstd/io/test.rs index d6f7f58f01c..73d52654ebf 100644 --- a/src/libstd/io/test.rs +++ b/src/libstd/io/test.rs @@ -150,7 +150,6 @@ mod darwin_fd_limit { rlim_cur: rlim_t, rlim_max: rlim_t } - #[nolink] extern { // name probably doesn't need to be mut, but the C function doesn't specify const fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint, diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index afd524e9d7a..c602c2fc27f 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -3306,7 +3306,6 @@ pub mod funcs { // or anything. The same is not true of POSIX. pub mod c95 { - #[nolink] pub mod ctype { use libc::types::os::arch::c95::{c_char, c_int}; @@ -3327,7 +3326,6 @@ pub mod funcs { } } - #[nolink] pub mod stdio { use libc::types::common::c95::{FILE, c_void, fpos_t}; use libc::types::os::arch::c95::{c_char, c_int, c_long, size_t}; @@ -3383,7 +3381,6 @@ pub mod funcs { } } - #[nolink] pub mod stdlib { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_double, c_int}; @@ -3416,7 +3413,6 @@ pub mod funcs { } } - #[nolink] pub mod string { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_int, size_t}; @@ -3461,7 +3457,6 @@ pub mod funcs { #[cfg(target_os = "win32")] pub mod posix88 { - #[nolink] pub mod stat_ { use libc::types::os::common::posix01::{stat, utimbuf}; use libc::types::os::arch::c95::{c_int, c_char, wchar_t}; @@ -3486,7 +3481,6 @@ pub mod funcs { } } - #[nolink] pub mod stdio { use libc::types::common::c95::FILE; use libc::types::os::arch::c95::{c_int, c_char}; @@ -3503,7 +3497,6 @@ pub mod funcs { } } - #[nolink] pub mod fcntl { use libc::types::os::arch::c95::{c_int, c_char, wchar_t}; extern { @@ -3518,12 +3511,10 @@ pub mod funcs { } } - #[nolink] pub mod dirent { // Not supplied at all. } - #[nolink] pub mod unistd { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_int, c_uint, c_char, @@ -3590,7 +3581,6 @@ pub mod funcs { use libc::types::os::arch::posix01::stat; use libc::types::os::arch::posix88::mode_t; - #[nolink] extern { pub fn chmod(path: *c_char, mode: mode_t) -> c_int; pub fn fchmod(fd: c_int, mode: mode_t) -> c_int; @@ -3618,7 +3608,6 @@ pub mod funcs { } } - #[nolink] pub mod stdio { use libc::types::common::c95::FILE; use libc::types::os::arch::c95::{c_char, c_int}; @@ -3631,7 +3620,6 @@ pub mod funcs { } } - #[nolink] pub mod fcntl { use libc::types::os::arch::c95::{c_char, c_int}; use libc::types::os::arch::posix88::mode_t; @@ -3644,7 +3632,6 @@ pub mod funcs { } } - #[nolink] pub mod dirent { use libc::types::common::posix88::{DIR, dirent_t}; use libc::types::os::arch::c95::{c_char, c_int, c_long}; @@ -3678,7 +3665,6 @@ pub mod funcs { } } - #[nolink] pub mod unistd { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_int, c_long, c_uint}; @@ -3748,7 +3734,6 @@ pub mod funcs { } } - #[nolink] pub mod signal { use libc::types::os::arch::c95::{c_int}; use libc::types::os::arch::posix88::{pid_t}; @@ -3758,7 +3743,6 @@ pub mod funcs { } } - #[nolink] pub mod mman { use libc::types::common::c95::{c_void}; use libc::types::os::arch::c95::{size_t, c_int, c_char}; @@ -3796,7 +3780,6 @@ pub mod funcs { #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] pub mod posix01 { - #[nolink] pub mod stat_ { use libc::types::os::arch::c95::{c_char, c_int}; use libc::types::os::arch::posix01::stat; @@ -3813,7 +3796,6 @@ pub mod funcs { } } - #[nolink] pub mod unistd { use libc::types::os::arch::c95::{c_char, c_int, size_t}; use libc::types::os::arch::posix88::{ssize_t, off_t}; @@ -3841,7 +3823,6 @@ pub mod funcs { } } - #[nolink] pub mod wait { use libc::types::os::arch::c95::{c_int}; use libc::types::os::arch::posix88::{pid_t}; @@ -3852,7 +3833,6 @@ pub mod funcs { } } - #[nolink] pub mod glob { use libc::types::os::arch::c95::{c_char, c_int}; use libc::types::os::common::posix01::{glob_t}; @@ -3867,7 +3847,6 @@ pub mod funcs { } } - #[nolink] pub mod mman { use libc::types::common::c95::{c_void}; use libc::types::os::arch::c95::{c_int, size_t}; @@ -4032,7 +4011,6 @@ pub mod funcs { } #[cfg(target_os = "macos")] - #[nolink] pub mod extra { use libc::types::os::arch::c95::{c_char, c_int}; @@ -4256,7 +4234,6 @@ pub mod funcs { use libc::types::os::arch::c95::{c_int, c_long}; use libc::types::os::arch::c99::intptr_t; - #[nolink] extern { #[link_name = "_commit"] pub fn commit(fd: c_int) -> c_int; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index e529daaa500..3a86aa3d6b6 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -615,7 +615,6 @@ pub fn errno() -> int { #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] fn errno_location() -> *c_int { - #[nolink] extern { fn __error() -> *c_int; } @@ -627,7 +626,6 @@ pub fn errno() -> int { #[cfg(target_os = "linux")] #[cfg(target_os = "android")] fn errno_location() -> *c_int { - #[nolink] extern { fn __errno_location() -> *c_int; } @@ -665,7 +663,6 @@ pub fn last_os_error() -> ~str { #[cfg(target_os = "freebsd")] fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int { - #[nolink] extern { fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int; @@ -681,7 +678,6 @@ pub fn last_os_error() -> ~str { #[cfg(target_os = "linux")] fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int { - #[nolink] extern { fn __xpg_strerror_r(errnum: c_int, buf: *mut c_char, diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index a3380b5db1d..f7588f6ca59 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -15,7 +15,7 @@ use c_str::{CString, ToCStr}; use clone::Clone; use cmp::Eq; use from_str::FromStr; -use hash::{Hash, sip}; +use io::Writer; use iter::{AdditiveIterator, Extendable, Iterator, Map}; use option::{Option, None, Some}; use str; @@ -88,10 +88,10 @@ impl ToCStr for Path { } } -impl Hash for Path { +impl<H: Writer> ::hash::Hash<H> for Path { #[inline] - fn hash(&self, s: &mut sip::SipState) { - self.repr.hash(s) + fn hash(&self, hasher: &mut H) { + self.repr.hash(hasher) } } diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 5b358819e41..6d05001beab 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -17,7 +17,7 @@ use clone::Clone; use container::Container; use cmp::Eq; use from_str::FromStr; -use hash::{Hash, sip}; +use io::Writer; use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Rev, Iterator, Map}; use option::{Option, Some, None}; use str; @@ -112,10 +112,10 @@ impl ToCStr for Path { } } -impl Hash for Path { +impl<H: Writer> ::hash::Hash<H> for Path { #[inline] - fn hash(&self, s: &mut sip::SipState) { - self.repr.hash(s) + fn hash(&self, hasher: &mut H) { + self.repr.hash(hasher) } } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 5bd14e717b1..1900d0ffedd 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -89,7 +89,7 @@ use clone::Clone; use cmp::{Eq, TotalEq, Ord, TotalOrd, Equiv, Ordering}; use container::{Container, Mutable}; use fmt; -use hash::{Hash, sip}; +use io::Writer; use iter::{Iterator, FromIterator, Extendable, range}; use iter::{Filter, AdditiveIterator, Map}; use iter::{Rev, DoubleEndedIterator, ExactSize}; @@ -1331,10 +1331,13 @@ impl<'a> Default for MaybeOwned<'a> { fn default() -> MaybeOwned<'a> { Slice("") } } -impl<'a> Hash for MaybeOwned<'a> { +impl<'a, H: Writer> ::hash::Hash<H> for MaybeOwned<'a> { #[inline] - fn hash(&self, s: &mut sip::SipState) { - self.as_slice().hash(s) + fn hash(&self, hasher: &mut H) { + match *self { + Slice(s) => s.hash(hasher), + Owned(ref s) => s.hash(hasher), + } } } |
