1 // Copyright 2013 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.
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.
19 #[cfg(test)] use uint;
22 Register a function to be run during runtime shutdown.
24 After all non-weak tasks have exited, registered exit functions will
25 execute, in random order, on the primary scheduler. Each function runs
26 in its own unsupervised task.
28 pub fn at_exit(f: ~fn()) {
30 let runner: &fn(*ExitFunctions) = exit_runner;
31 let runner_pair: sys::Closure = cast::transmute(runner);
32 let runner_ptr = runner_pair.code;
33 let runner_ptr = cast::transmute(runner_ptr);
34 rustrt::rust_register_exit_function(runner_ptr, ~f);
38 // NB: The double pointer indirection here is because ~fn() is a fat
39 // pointer and due to FFI problems I am more comfortable making the
40 // interface use a normal pointer
45 pub fn rust_register_exit_function(runner: *c_void, f: ~~fn());
49 struct ExitFunctions {
50 // The number of exit functions
52 // The buffer of exit functions
56 fn exit_runner(exit_fns: *ExitFunctions) {
57 let exit_fns = unsafe { &*exit_fns };
58 let count = (*exit_fns).count;
59 let start = (*exit_fns).start;
61 // NB: from_buf memcpys from the source, which will
62 // give us ownership of the array of functions
63 let mut exit_fns_vec = unsafe { vec::from_buf(start, count as uint) };
64 // Let's not make any promises about execution order
65 let mut rng = rand::rng();
66 rng.shuffle_mut(exit_fns_vec);
68 debug!("running %u exit functions", exit_fns_vec.len());
70 while !exit_fns_vec.is_empty() {
71 match exit_fns_vec.pop() {
73 let mut task = task::task();
91 fn test_at_exit_many() {
93 for uint::range(20, 100) |j| {