Skip to content

Commit

Permalink
core: add 3rd proposed interface (trap/in) to conditions.
Browse files Browse the repository at this point in the history
  • Loading branch information
graydon committed Oct 19, 2012
1 parent 0243d86 commit 89de49c
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions src/libcore/condition.rs
Expand Up @@ -51,6 +51,11 @@ struct HandleBlock<T, U:Copy> {
}
}

struct Trap<T, U:Copy> {
cond: &Condition<T,U>,
handler: @Handler<T, U>
}

impl<T, U: Copy> ProtectBlock<T,U> {
fn handle(&self, h: &self/fn(&T) ->U) -> HandleBlock/&self<T,U> {
unsafe {
Expand All @@ -65,6 +70,20 @@ impl<T, U: Copy> ProtectBlock<T,U> {
}



impl<T, U: Copy> Trap<T,U> {
fn in<V: Copy>(&self, inner: &self/fn() -> V) -> V {
unsafe {
let prev = task::local_data::local_data_get(self.cond.key);
let _g = Guard { cond: self.cond,
prev: prev };
debug!("Trap: pushing handler to TLS");
task::local_data::local_data_set(self.cond.key, self.handler);
inner()
}
}
}

impl<T, U: Copy> Condition<T,U> {

fn guard(&self, h: &self/fn(&T) ->U) -> Guard/&self<T,U> {
Expand All @@ -79,6 +98,14 @@ impl<T, U: Copy> Condition<T,U> {
}
}

fn trap(&self, h: &self/fn(&T) ->U) -> Trap/&self<T,U> {
unsafe {
let p : *RustClosure = ::cast::transmute(&h);
let h = @Handler{handle: *p};
move Trap { cond: self, handler: h }
}
}

fn protect(&self, inner: &self/fn()) -> ProtectBlock/&self<T,U> {
unsafe {
// transmutation to avoid copying non-copyable, should
Expand Down Expand Up @@ -229,3 +256,45 @@ fn nested_guard_test_outer() {

assert outer_trapped;
}



#[cfg(test)]
fn nested_trap_test_inner() {
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };

let mut inner_trapped = false;

do sadness_condition.trap(|_j| {
debug!("nested_trap_test_inner: in handler");
inner_trapped = true;
0
}).in {
debug!("nested_trap_test_inner: in protected block");
trouble(1);
}

assert inner_trapped;
}

#[test]
fn nested_trap_test_outer() {

let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };

let mut outer_trapped = false;

do sadness_condition.trap(|_j| {
debug!("nested_trap_test_outer: in handler");
outer_trapped = true; 0
}).in {
debug!("nested_guard_test_outer: in protected block");
nested_trap_test_inner();
trouble(1);
}


assert outer_trapped;
}

0 comments on commit 89de49c

Please sign in to comment.