diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2013-12-04 15:20:26 -0800 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2013-12-10 15:13:12 -0800 |
| commit | ec5603bf13ccb95c311fe5ca193a32efe07147a2 (patch) | |
| tree | 6cf2f33e901d673ba63fa781ddb5167beaae42f8 /src/libstd | |
| parent | ab3bec91d77150e434ac1480fbb3935213e33dca (diff) | |
| download | rust-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.rs | 20 | ||||
| -rw-r--r-- | src/libstd/io/mod.rs | 5 | ||||
| -rw-r--r-- | src/libstd/os.rs | 4 | ||||
| -rw-r--r-- | src/libstd/run.rs | 29 |
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(); |
