librustpkg: Make io::ignore_io_error() use RAII; remove a few more

cells.
This commit is contained in:
Patrick Walton 2013-12-04 15:20:26 -08:00
parent ab3bec91d7
commit ec5603bf13
7 changed files with 59 additions and 27 deletions

View File

@ -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");

View File

@ -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);

View File

@ -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>
}

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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();