Skip to content

Commit c009bfd

Browse files
committed
Make at_exit initialize lazily
1 parent b66681c commit c009bfd

File tree

4 files changed

+25
-23
lines changed

4 files changed

+25
-23
lines changed

src/liblibc/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub use funcs::c95::stdio::{fread, freopen, fseek, fsetpos, ftell};
138138
pub use funcs::c95::stdio::{fwrite, perror, puts, remove, rename, rewind};
139139
pub use funcs::c95::stdio::{setbuf, setvbuf, tmpfile, ungetc};
140140

141-
pub use funcs::c95::stdlib::{abs, atof, atoi, calloc, exit, _exit};
141+
pub use funcs::c95::stdlib::{abs, atof, atoi, calloc, exit, _exit, atexit};
142142
pub use funcs::c95::stdlib::{free, getenv, labs, malloc, rand};
143143
pub use funcs::c95::stdlib::{realloc, srand, strtod, strtol};
144144
pub use funcs::c95::stdlib::{strtoul, system};
@@ -4102,7 +4102,7 @@ pub mod funcs {
41024102
pub fn free(p: *mut c_void);
41034103
pub fn exit(status: c_int) -> !;
41044104
pub fn _exit(status: c_int) -> !;
4105-
// Omitted: atexit.
4105+
pub fn atexit(cb: extern fn()) -> c_int;
41064106
pub fn system(s: *const c_char) -> c_int;
41074107
pub fn getenv(s: *const c_char) -> *mut c_char;
41084108
// Omitted: bsearch, qsort

src/libstd/os.rs

-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ use boxed::Box;
4343
use ops::{Drop, FnOnce};
4444
use option::Option;
4545
use option::Option::{Some, None};
46-
use os;
4746
use path::{Path, GenericPath, BytesContainer};
4847
use sys;
4948
use ptr::RawPtr;

src/libstd/rt/at_exit_imp.rs

+23-18
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,32 @@
1414
1515
use core::prelude::*;
1616

17+
use libc;
1718
use boxed::Box;
1819
use vec::Vec;
19-
use sync::atomic;
20+
use sync::{atomic, Once, ONCE_INIT};
2021
use mem;
2122
use thunk::Thunk;
2223

2324
use rt::exclusive::Exclusive;
2425

2526
type Queue = Exclusive<Vec<Thunk>>;
2627

28+
static INIT: Once = ONCE_INIT;
2729
static QUEUE: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
2830
static RUNNING: atomic::AtomicBool = atomic::INIT_ATOMIC_BOOL;
2931

30-
pub fn init() {
32+
fn init() {
3133
let state: Box<Queue> = box Exclusive::new(Vec::new());
3234
unsafe {
33-
rtassert!(!RUNNING.load(atomic::SeqCst));
34-
assert!(QUEUE.swap(mem::transmute(state), atomic::SeqCst) == 0);
35-
}
36-
}
37-
38-
pub fn push(f: Thunk) {
39-
unsafe {
40-
// Note that the check against 0 for the queue pointer is not atomic at
41-
// all with respect to `run`, meaning that this could theoretically be a
42-
// use-after-free. There's not much we can do to protect against that,
43-
// however. Let's just assume a well-behaved runtime and go from there!
44-
rtassert!(!RUNNING.load(atomic::SeqCst));
45-
let queue = QUEUE.load(atomic::SeqCst);
46-
rtassert!(queue != 0);
47-
(*(queue as *const Queue)).lock().push(f);
35+
QUEUE.store(mem::transmute(state), atomic::SeqCst);
36+
libc::atexit(run);
4837
}
4938
}
5039

51-
pub fn run() {
40+
// Note: this is private and so can only be called via atexit above,
41+
// which guarantees initialization.
42+
extern fn run() {
5243
let cur = unsafe {
5344
rtassert!(!RUNNING.load(atomic::SeqCst));
5445
let queue = QUEUE.swap(0, atomic::SeqCst);
@@ -63,3 +54,17 @@ pub fn run() {
6354
to_run.invoke(());
6455
}
6556
}
57+
58+
pub fn push(f: Thunk) {
59+
INIT.doit(init);
60+
unsafe {
61+
// Note that the check against 0 for the queue pointer is not atomic at
62+
// all with respect to `run`, meaning that this could theoretically be a
63+
// use-after-free. There's not much we can do to protect against that,
64+
// however. Let's just assume a well-behaved runtime and go from there!
65+
rtassert!(!RUNNING.load(atomic::SeqCst));
66+
let queue = QUEUE.load(atomic::SeqCst);
67+
rtassert!(queue != 0);
68+
(*(queue as *const Queue)).lock().push(f);
69+
}
70+
}

src/libstd/rt/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ pub fn init(argc: int, argv: *const *const u8) {
100100
unsafe {
101101
args::init(argc, argv);
102102
local_ptr::init();
103-
at_exit_imp::init();
104103
thread::init();
105104
unwind::register(failure::on_fail);
106105
}
@@ -212,7 +211,6 @@ pub unsafe fn cleanup() {
212211
args::cleanup();
213212
thread::cleanup();
214213
local_ptr::cleanup();
215-
at_exit_imp::run();
216214
}
217215

218216
// FIXME: these probably shouldn't be public...

0 commit comments

Comments
 (0)