about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-12-04 15:20:26 -0800
committerPatrick Walton <pcwalton@mimiga.net>2013-12-10 15:13:12 -0800
commitec5603bf13ccb95c311fe5ca193a32efe07147a2 (patch)
tree6cf2f33e901d673ba63fa781ddb5167beaae42f8
parentab3bec91d77150e434ac1480fbb3935213e33dca (diff)
downloadrust-ec5603bf13ccb95c311fe5ca193a32efe07147a2.tar.gz
rust-ec5603bf13ccb95c311fe5ca193a32efe07147a2.zip
librustpkg: Make `io::ignore_io_error()` use RAII; remove a few more
cells.
-rw-r--r--src/librustpkg/installed_packages.rs15
-rw-r--r--src/librustpkg/path_util.rs5
-rw-r--r--src/libstd/condition.rs20
-rw-r--r--src/libstd/io/mod.rs5
-rw-r--r--src/libstd/os.rs4
-rw-r--r--src/libstd/run.rs29
-rw-r--r--src/test/bench/shootout-k-nucleotide-pipes.rs8
7 files changed, 59 insertions, 27 deletions
diff --git a/src/librustpkg/installed_packages.rs b/src/librustpkg/installed_packages.rs
index b1e3d1bd879..48c25a53682 100644
--- a/src/librustpkg/installed_packages.rs
+++ b/src/librustpkg/installed_packages.rs
@@ -19,7 +19,10 @@ use std::io::fs;
 pub fn list_installed_packages(f: |&PkgId| -> bool) -> bool  {
     let workspaces = rust_path();
     for p in workspaces.iter() {
-        let binfiles = io::ignore_io_error(|| fs::readdir(&p.join("bin")));
+        let binfiles = {
+            let _guard = io::ignore_io_error();
+            fs::readdir(&p.join("bin"))
+        };
         for exec in binfiles.iter() {
             // FIXME (#9639): This needs to handle non-utf8 paths
             match exec.filestem_str() {
@@ -31,7 +34,10 @@ pub fn list_installed_packages(f: |&PkgId| -> bool) -> bool  {
                 }
             }
         }
-        let libfiles = io::ignore_io_error(|| fs::readdir(&p.join("lib")));
+        let libfiles = {
+            let _guard = io::ignore_io_error();
+            fs::readdir(&p.join("lib"))
+        };
         for lib in libfiles.iter() {
             debug!("Full name: {}", lib.display());
             match has_library(lib) {
@@ -55,7 +61,10 @@ pub fn list_installed_packages(f: |&PkgId| -> bool) -> bool  {
 }
 
 pub fn has_library(p: &Path) -> Option<~str> {
-    let files = io::ignore_io_error(|| fs::readdir(p));
+    let files = {
+        let _guard = io::ignore_io_error();
+        fs::readdir(p)
+    };
     for path in files.iter() {
         if path.extension_str() == Some(os::consts::DLL_EXTENSION) {
             let stuff : &str = path.filestem_str().expect("has_library: weird path");
diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs
index 4b5e1ce8727..7a17d362625 100644
--- a/src/librustpkg/path_util.rs
+++ b/src/librustpkg/path_util.rs
@@ -217,7 +217,10 @@ pub fn system_library(sysroot: &Path, lib_name: &str) -> Option<Path> {
 
 fn library_in(short_name: &str, version: &Version, dir_to_search: &Path) -> Option<Path> {
     debug!("Listing directory {}", dir_to_search.display());
-    let dir_contents = io::ignore_io_error(|| fs::readdir(dir_to_search));
+    let dir_contents = {
+        let _guard = io::ignore_io_error();
+        fs::readdir(dir_to_search)
+    };
     debug!("dir has {:?} entries", dir_contents.len());
 
     let lib_prefix = format!("{}{}", os::consts::DLL_PREFIX, short_name);
diff --git a/src/libstd/condition.rs b/src/libstd/condition.rs
index e34e94ac10c..c5d6ce2f3df 100644
--- a/src/libstd/condition.rs
+++ b/src/libstd/condition.rs
@@ -162,7 +162,7 @@ impl<T, U> Condition<T, U> {
 ///
 /// Normally this object is not dealt with directly, but rather it's directly
 /// used after being returned from `trap`
-struct Trap<'self, T, U> {
+pub struct Trap<'self, T, U> {
     priv cond: &'self Condition<T, U>,
     priv handler: @Handler<T, U>
 }
@@ -187,10 +187,24 @@ impl<'self, T, U> Trap<'self, T, U> {
         local_data::set(self.cond.key, self.handler);
         inner()
     }
+
+    /// Returns a guard that will automatically reset the condition upon
+    /// exit of the scope. This is useful if you want to use conditions with
+    /// an RAII pattern.
+    pub fn guard(&self) -> Guard<'self,T,U> {
+        let guard = Guard {
+            cond: self.cond
+        };
+        debug!("Guard: pushing handler to TLS");
+        local_data::set(self.cond.key, self.handler);
+        guard
+    }
 }
 
-#[doc(hidden)]
-struct Guard<'self, T, U> {
+/// A guard that will automatically reset the condition handler upon exit of
+/// the scope. This is useful if you want to use conditions with an RAII
+/// pattern.
+pub struct Guard<'self, T, U> {
     priv cond: &'self Condition<T, U>
 }
 
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index edc6728a0c1..d5e216e2426 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -241,6 +241,7 @@ Out of scope
 #[allow(missing_doc)];
 
 use cast;
+use condition::Guard;
 use container::Container;
 use int;
 use iter::Iterator;
@@ -394,12 +395,12 @@ condition! {
 
 /// Helper for wrapper calls where you want to
 /// ignore any io_errors that might be raised
-pub fn ignore_io_error<T>(cb: || -> T) -> T {
+pub fn ignore_io_error() -> Guard<'static,IoError,()> {
     io_error::cond.trap(|_| {
         // just swallow the error.. downstream users
         // who can make a decision based on a None result
         // won't care
-    }).inside(|| cb())
+    }).guard()
 }
 
 /// Helper for catching an I/O error and wrapping it in a Result object. The
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index ff939310865..bcd353bab7a 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -1477,7 +1477,9 @@ mod tests {
             assert!(*chunk.data == 0xbe);
             close(fd);
         }
-        io::ignore_io_error(|| fs::unlink(&path));
+
+        let _guard = io::ignore_io_error();
+        fs::unlink(&path);
     }
 
     // More recursive_mkdir tests are in extra::tempfile
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index 2447bba98d6..f4c6cdbd934 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -12,7 +12,6 @@
 
 #[allow(missing_doc)];
 
-use cell::Cell;
 use comm::{stream, SharedChan};
 use io::Reader;
 use io::process::ProcessExit;
@@ -212,8 +211,8 @@ impl Process {
      */
     pub fn finish_with_output(&mut self) -> ProcessOutput {
         self.close_input();
-        let output = Cell::new(self.inner.io[1].take());
-        let error = Cell::new(self.inner.io[2].take());
+        let output = self.inner.io[1].take();
+        let error = self.inner.io[2].take();
 
         // Spawn two entire schedulers to read both stdout and sterr
         // in parallel so we don't deadlock while blocking on one
@@ -224,20 +223,20 @@ impl Process {
         let ch_clone = ch.clone();
 
         do spawn {
-            io::ignore_io_error(|| {
-                match error.take() {
-                    Some(ref mut e) => ch.send((2, e.read_to_end())),
-                    None => ch.send((2, ~[]))
-                }
-            })
+            let _guard = io::ignore_io_error();
+            let mut error = error;
+            match error {
+                Some(ref mut e) => ch.send((2, e.read_to_end())),
+                None => ch.send((2, ~[]))
+            }
         }
         do spawn {
-            io::ignore_io_error(|| {
-                match output.take() {
-                    Some(ref mut e) => ch_clone.send((1, e.read_to_end())),
-                    None => ch_clone.send((1, ~[]))
-                }
-            })
+            let _guard = io::ignore_io_error();
+            let mut output = output;
+            match output {
+                Some(ref mut e) => ch_clone.send((1, e.read_to_end())),
+                None => ch_clone.send((1, ~[]))
+            }
         }
 
         let status = self.finish();
diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs
index 76d2ca1f30b..ac2b1958f93 100644
--- a/src/test/bench/shootout-k-nucleotide-pipes.rs
+++ b/src/test/bench/shootout-k-nucleotide-pipes.rs
@@ -189,8 +189,12 @@ fn main() {
    let mut proc_mode = false;
 
    loop {
-       let line = match io::ignore_io_error(|| rdr.read_line()) {
-           Some(ln) => ln, None => break,
+       let line = {
+           let _guard = io::ignore_io_error();
+           match rdr.read_line() {
+               Some(ln) => ln,
+               None => break,
+           }
        };
        let line = line.trim().to_owned();