Created
August 11, 2013 21:10
-
-
Save orenbenkiki/6206863 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Intern a string using the task local interner. | |
pub fn intern(burrowed: &str) -> Intern { | |
do local_data::get(KEY_ARC_INTERNER) |maybe_arc_interner| { | |
match maybe_arc_interner { | |
None => fail!("no task local ARC for global interner"), | |
Some(arc_interner) => { | |
// TRICKY: Only obtain a read lock for the common case | |
// where the string was previously interned. | |
do arc_interner.read |interner| { | |
match interner.str_to_intern.find(&burrowed.to_str()) { | |
Some(intern) => *intern, | |
None => { | |
// TRICKY: If we didn't find it above, we need | |
// to get a write lock and re-find it, to | |
// ensure no other task sneaked in and added it | |
// between the above find and obtaining the | |
// write lock below. This sort of race | |
// condition is why one shouldn't write code | |
// using locks unless it is *really* necessary. | |
// | |
// OOPS: This doesn't work because we are | |
// trying to get a write lock while (our!) read | |
// lock is in effect; so this deadlocks. There | |
// is no "write_upgrade" | |
do arc_interner.write |mut_interner: &mut Interner| { | |
let intern = do mut_interner.str_to_intern.find_or_insert_with(burrowed.to_str()) |owned| { | |
mut_interner.id_to_str.push(owned.clone()); | |
Intern { id: mut_interner.id_to_str.len() - 1 } | |
}; | |
*intern | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Intern a string using the task local interner. | |
pub fn intern(burrowed: &str) -> Intern { | |
do local_data::get(KEY_ARC_INTERNER) |maybe_arc_interner| { | |
match maybe_arc_interner { | |
None => fail!("no task local ARC for global interner"), | |
Some(arc_interner) => { | |
// TRICKY: Only obtain a read lock for the common case | |
// where the string was previously interned. | |
// | |
// OOPS: The compiler can't deduce the lifetime of | |
// maybe_intern. | |
let maybe_intern = do arc_interner.read |interner| { | |
interner.str_to_intern.find(&burrowed.to_str()) | |
}; | |
match maybe_intern { | |
Some(intern) => *intern, | |
None => { | |
// TRICKY: If we didn't find it above, we need | |
// to get a write lock and re-find it, to | |
// ensure no other task sneaked in and added it | |
// between the above find and obtaining the | |
// write lock below. This sort of race | |
// condition is why one shouldn't write code | |
// using locks unless it is *really* necessary. | |
do arc_interner.write |mut_interner: &mut Interner| { | |
let intern = do mut_interner.str_to_intern.find_or_insert_with(burrowed.to_str()) |owned| { | |
mut_interner.id_to_str.push(owned.clone()); | |
Intern { id: mut_interner.id_to_str.len() - 1 } | |
}; | |
*intern | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Intern a string using the task local interner. | |
pub fn intern(burrowed: &str) -> Intern { | |
do local_data::get(KEY_ARC_INTERNER) |maybe_arc_interner| { | |
match maybe_arc_interner { | |
None => fail!("no task local ARC for global interner"), | |
Some(arc_interner) => { | |
// TRICKY: Only obtain a read lock for the common case | |
// where the string was previously interned. | |
// | |
// OOPS: The compiler dies with an internal bug error... | |
let maybe_intern: &'self Option<&Intern> = do arc_interner.read |interner| { | |
interner.str_to_intern.find(&burrowed.to_str()) | |
}; | |
match maybe_intern { | |
Some(intern) => *intern, | |
None => { | |
// TRICKY: If we didn't find it above, we need | |
// to get a write lock and re-find it, to | |
// ensure no other task sneaked in and added it | |
// between the above find and obtaining the | |
// write lock below. This sort of race | |
// condition is why one shouldn't write code | |
// using locks unless it is *really* necessary. | |
do arc_interner.write |mut_interner: &mut Interner| { | |
let intern = do mut_interner.str_to_intern.find_or_insert_with(burrowed.to_str()) |owned| { | |
mut_interner.id_to_str.push(owned.clone()); | |
Intern { id: mut_interner.id_to_str.len() - 1 } | |
}; | |
*intern | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
oren@LinuxBox:~/Rust/workspace$ RUST_LOG=rustc=1,::rt::backtrace rust test src/anthill/crate.rs | |
task <unnamed> failed at 'assertion failed: rp.is_none()', /home/oren/Rust/rust/src/librustc/middle/typeck/collect.rs:1061 | |
error: internal compiler error: unexpected failure | |
note: the compiler hit an unexpected failure path. this is a bug | |
note: try running with RUST_LOG=rustc=1,::rt::backtrace to get further details and report the results to github.com/mozilla/rust/issues | |
task <unnamed> failed at 'explicit failure', /home/oren/Rust/rust/src/librustc/rustc.rs:375 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment