about summary refs log tree commit diff
path: root/src/libstd
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 /src/libstd
parentab3bec91d77150e434ac1480fbb3935213e33dca (diff)
downloadrust-ec5603bf13ccb95c311fe5ca193a32efe07147a2.tar.gz
rust-ec5603bf13ccb95c311fe5ca193a32efe07147a2.zip
librustpkg: Make `io::ignore_io_error()` use RAII; remove a few more
cells.
Diffstat (limited to 'src/libstd')
-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
4 files changed, 37 insertions, 21 deletions
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();