mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 06:47:34 +00:00
Implement std::rt::at_exit
This routine is currently only used to clean up the timer helper thread in the libnative implementation, but there are possibly other uses for this. The documentation is clear that the procedures are *not* run with any task context and hence have very little available to them. I also opted to disallow at_exit inside of at_exit and just abort the process at that point.
This commit is contained in:
parent
fce792249e
commit
530909f2d8
65
src/libstd/rt/at_exit_imp.rs
Normal file
65
src/libstd/rt/at_exit_imp.rs
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation of running at_exit routines
|
||||
//!
|
||||
//! Documentation can be found on the `rt::at_exit` function.
|
||||
|
||||
use cast;
|
||||
use option::{Some, None};
|
||||
use ptr::RawPtr;
|
||||
use unstable::sync::Exclusive;
|
||||
use util;
|
||||
|
||||
type Queue = Exclusive<~[proc()]>;
|
||||
|
||||
static mut QUEUE: *mut Queue = 0 as *mut Queue;
|
||||
static mut RUNNING: bool = false;
|
||||
|
||||
pub fn init() {
|
||||
unsafe {
|
||||
rtassert!(!RUNNING);
|
||||
rtassert!(QUEUE.is_null());
|
||||
let state: ~Queue = ~Exclusive::new(~[]);
|
||||
QUEUE = cast::transmute(state);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(f: proc()) {
|
||||
unsafe {
|
||||
rtassert!(!RUNNING);
|
||||
rtassert!(!QUEUE.is_null());
|
||||
let state: &mut Queue = cast::transmute(QUEUE);
|
||||
let mut f = Some(f);
|
||||
state.with(|arr| {
|
||||
arr.push(f.take_unwrap());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
let vec = unsafe {
|
||||
rtassert!(!RUNNING);
|
||||
rtassert!(!QUEUE.is_null());
|
||||
RUNNING = true;
|
||||
let state: ~Queue = cast::transmute(QUEUE);
|
||||
QUEUE = 0 as *mut Queue;
|
||||
let mut vec = None;
|
||||
state.with(|arr| {
|
||||
vec = Some(util::replace(arr, ~[]));
|
||||
});
|
||||
vec.take_unwrap()
|
||||
};
|
||||
|
||||
|
||||
for f in vec.move_iter() {
|
||||
f();
|
||||
}
|
||||
}
|
@ -127,6 +127,9 @@ mod util;
|
||||
// Global command line argument storage
|
||||
pub mod args;
|
||||
|
||||
// Support for running procedures when a program has exited.
|
||||
mod at_exit_imp;
|
||||
|
||||
/// The default error code of the rust runtime if the main task fails instead
|
||||
/// of exiting cleanly.
|
||||
pub static DEFAULT_ERROR_CODE: int = 101;
|
||||
@ -171,9 +174,27 @@ pub fn init(argc: int, argv: **u8) {
|
||||
env::init();
|
||||
logging::init();
|
||||
local_ptr::init();
|
||||
at_exit_imp::init();
|
||||
}
|
||||
}
|
||||
|
||||
/// Enqueues a procedure to run when the runtime is cleaned up
|
||||
///
|
||||
/// The procedure passed to this function will be executed as part of the
|
||||
/// runtime cleanup phase. For normal rust programs, this means that it will run
|
||||
/// after all other tasks have exited.
|
||||
///
|
||||
/// The procedure is *not* executed with a local `Task` available to it, so
|
||||
/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
|
||||
/// This is meant for "bare bones" usage to clean up runtime details, this is
|
||||
/// not meant as a general-purpose "let's clean everything up" function.
|
||||
///
|
||||
/// It is forbidden for procedures to register more `at_exit` handlers when they
|
||||
/// are running, and doing so will lead to a process abort.
|
||||
pub fn at_exit(f: proc()) {
|
||||
at_exit_imp::push(f);
|
||||
}
|
||||
|
||||
/// One-time runtime cleanup.
|
||||
///
|
||||
/// This function is unsafe because it performs no checks to ensure that the
|
||||
@ -184,6 +205,7 @@ pub fn init(argc: int, argv: **u8) {
|
||||
/// Invoking cleanup while portions of the runtime are still in use may cause
|
||||
/// undefined behavior.
|
||||
pub unsafe fn cleanup() {
|
||||
at_exit_imp::run();
|
||||
args::cleanup();
|
||||
local_ptr::cleanup();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user