core: add 3rd proposed interface (trap/in) to conditions.
This commit is contained in:
parent
0243d86e19
commit
89de49cecd
@ -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 {
|
||||
@ -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> {
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user