Skip to content

Instantly share code, notes, and snippets.

@mitsuhiko
Created February 13, 2013 17:05
Show Gist options
  • Save mitsuhiko/4946140 to your computer and use it in GitHub Desktop.
Save mitsuhiko/4946140 to your computer and use it in GitHub Desktop.
/* a macro that defines a context variable that is stored in thread local
storage. It's implemented as a module that exports a `get`, `set` and
`set_to` function. `set_to` acts as a stack. */
macro_rules! context_var (($name:ident : $t:ty) => (
mod $name {
/* internal tls key helper */
fn key(_x: @$t) {}
/* checks if the variable is set */
pub fn is_set() -> bool { unsafe {
match task::local_data::local_data_get(key) {
Some(ref _x) => true,
None => false
}
} }
/* returns the current value of that variable or fails with an error */
pub fn get() -> @$t { unsafe {
match move task::local_data::local_data_get(key) {
Some(move x) => move x,
None => {
die!(fmt!("%s::get() tried to return value \
but no value was set",
stringify!($name)))
}
}
} }
/* sets the variable to a new value */
pub fn set(value: @$t) { unsafe {
task::local_data::local_data_set(key, value);
} }
/* unsets the value */
pub fn unset() { unsafe {
task::local_data::local_data_pop(key);
}}
/* temporarily overrides the variable with a new value */
pub fn set_to(value: @$t, cb: fn()) { unsafe {
let old = move task::local_data::local_data_pop(key);
task::local_data::local_data_set(key, value);
cb();
match (old) {
None => {}
Some(ref x) => {
task::local_data::local_data_set(key, *x);
}
}
} }
}
))
context_var!(language: ~str)
fn print_language() {
if language::is_set() {
io::println(fmt!("Your language is: %?", language::get()));
} else {
io::println("No language is set");
}
}
fn main() {
io::print("main task before setting: ");
print_language();
do language::set_to(@~"en_US") {
io::print("main task in block: ");
print_language();
do task::spawn {
io::print("in another task: ");
print_language();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment