]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/task-killjoin-rsrc.rs
c811e548f3fb18f0226b94baba937a32634ea43e
[rust.git] / src / test / run-pass / task-killjoin-rsrc.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // xfail-win32
12
13 // A port of task-killjoin to use a class with a dtor to manage
14 // the join.
15
16 use std::cell::Cell;
17 use std::comm::*;
18 use std::ptr;
19 use std::task;
20
21 struct notify {
22     ch: Chan<bool>, v: @mut bool,
23 }
24
25 #[unsafe_destructor]
26 impl Drop for notify {
27     fn drop(&self) {
28         unsafe {
29             error!("notify: task=%? v=%x unwinding=%b b=%b",
30                    0,
31                    ptr::to_unsafe_ptr(&(*(self.v))) as uint,
32                    task::failing(),
33                    *(self.v));
34             let b = *(self.v);
35             self.ch.send(b);
36         }
37     }
38 }
39
40 fn notify(ch: Chan<bool>, v: @mut bool) -> notify {
41     notify {
42         ch: ch,
43         v: v
44     }
45 }
46
47 fn joinable(f: ~fn()) -> Port<bool> {
48     fn wrapper(c: Chan<bool>, f: &fn()) {
49         let b = @mut false;
50         error!("wrapper: task=%? allocated v=%x",
51                0,
52                ptr::to_unsafe_ptr(&(*b)) as uint);
53         let _r = notify(c, b);
54         f();
55         *b = true;
56     }
57     let (p, c) = stream();
58     let c = Cell::new(c);
59     do task::spawn_unlinked {
60         let ccc = c.take();
61         wrapper(ccc, f)
62     }
63     p
64 }
65
66 fn join(port: Port<bool>) -> bool {
67     port.recv()
68 }
69
70 fn supervised() {
71     // Yield to make sure the supervisor joins before we
72     // fail. This is currently not needed because the supervisor
73     // runs first, but I can imagine that changing.
74     error!("supervised task=%?", 0);
75     task::yield();
76     fail!();
77 }
78
79 fn supervisor() {
80     error!("supervisor task=%?", 0);
81     let t = joinable(supervised);
82     join(t);
83 }
84
85 pub fn main() {
86     join(joinable(supervisor));
87 }