Skip to content

Commit

Permalink
std: Run at_exit cleanup on process::exit
Browse files Browse the repository at this point in the history
This adds a call to `rt::cleanup` on `process::exit` to make sure we clean up
after ourselves on the way out from Rust.

Closes #28065
  • Loading branch information
alexcrichton committed Sep 3, 2015
1 parent 8dba06a commit 04c09f9
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/libstd/process.rs
Expand Up @@ -582,6 +582,7 @@ impl Child {
/// to run.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn exit(code: i32) -> ! {
::rt::cleanup();
::sys::os::exit(code)
}

Expand Down
1 change: 0 additions & 1 deletion src/libstd/rt/args.rs
Expand Up @@ -64,7 +64,6 @@ mod imp {

pub unsafe fn cleanup() {
take();
LOCK.destroy();
}

pub fn take() -> Option<Vec<Vec<u8>>> {
Expand Down
4 changes: 0 additions & 4 deletions src/libstd/rt/at_exit_imp.rs
Expand Up @@ -12,10 +12,6 @@
//!
//! Documentation can be found on the `rt::at_exit` function.

// FIXME: switch this to use atexit. Currently this
// segfaults (the queue's memory is mysteriously gone), so
// instead the cleanup is tied to the `std::rt` entry point.

use alloc::boxed::FnBox;
use boxed::Box;
use sys_common::mutex::Mutex;
Expand Down
20 changes: 8 additions & 12 deletions src/libstd/rt/mod.rs
Expand Up @@ -23,6 +23,7 @@
#![allow(missing_docs)]

use prelude::v1::*;
use sync::Once;
use sys;
use thread;

Expand Down Expand Up @@ -124,16 +125,11 @@ pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> {
}

/// One-time runtime cleanup.
///
/// This function is unsafe because it performs no checks to ensure that the
/// runtime has completely ceased running. It is the responsibility of the
/// caller to ensure that the runtime is entirely shut down and nothing will be
/// poking around at the internal components.
///
/// Invoking cleanup while portions of the runtime are still in use may cause
/// undefined behavior.
pub unsafe fn cleanup() {
args::cleanup();
sys::stack_overflow::cleanup();
at_exit_imp::cleanup();
pub fn cleanup() {
static CLEANUP: Once = Once::new();
CLEANUP.call_once(|| unsafe {
args::cleanup();
sys::stack_overflow::cleanup();
at_exit_imp::cleanup();
});
}
25 changes: 25 additions & 0 deletions src/test/run-pass/exit-flushes.rs
@@ -0,0 +1,25 @@
// Copyright 2015 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.

use std::env;
use std::process::{exit, Command};

fn main() {
if env::args().len() > 1 {
print!("hello!");
exit(0);
} else {
let out = Command::new(env::args().next().unwrap()).arg("foo")
.output().unwrap();
assert!(out.status.success());
assert_eq!(String::from_utf8(out.stdout).unwrap(), "hello!");
assert_eq!(String::from_utf8(out.stderr).unwrap(), "");
}
}

0 comments on commit 04c09f9

Please sign in to comment.