about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-03-12 15:07:06 -0700
committerbors <bors@rust-lang.org>2014-03-12 15:07:06 -0700
commit4d64441bcb820cf35d3e39dde8514c46765a12a6 (patch)
tree541bf3eb9112d8e40475b90f6da342980bbde7f8 /src/libstd
parent3316a0e6b2ad9352bab58e7c046ef3d212411d82 (diff)
parent3f2434eee3f7fa72bf7a8693aef3932d563cf8d5 (diff)
downloadrust-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.rs19
-rw-r--r--src/libstd/comm/select.rs52
-rw-r--r--src/libstd/io/mod.rs34
-rw-r--r--src/libstd/io/test.rs1
-rw-r--r--src/libstd/libc.rs23
-rw-r--r--src/libstd/os.rs4
-rw-r--r--src/libstd/path/posix.rs8
-rw-r--r--src/libstd/path/windows.rs8
-rw-r--r--src/libstd/str.rs11
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),
+        }
     }
 }