Skip to content

Commit aec67c2

Browse files
committed
Revert "std: Re-enable at_exit()"
This reverts commit 9e224c2. Conflicts: src/libstd/sys/windows/os.rs
1 parent 582cba1 commit aec67c2

39 files changed

+245
-191
lines changed

src/liblog/lib.rs

+8-26
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ use std::mem;
177177
use std::os;
178178
use std::rt;
179179
use std::slice;
180-
use std::sync::{Once, ONCE_INIT, StaticMutex, MUTEX_INIT};
180+
use std::sync::{Once, ONCE_INIT};
181181

182182
use regex::Regex;
183183

@@ -193,8 +193,6 @@ pub const MAX_LOG_LEVEL: u32 = 255;
193193
/// The default logging level of a crate if no other is specified.
194194
const DEFAULT_LOG_LEVEL: u32 = 1;
195195

196-
static LOCK: StaticMutex = MUTEX_INIT;
197-
198196
/// An unsafe constant that is the maximum logging level of any module
199197
/// specified. This is the first line of defense to determining whether a
200198
/// logging statement should be run.
@@ -281,18 +279,9 @@ impl Drop for DefaultLogger {
281279
pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
282280
// Test the literal string from args against the current filter, if there
283281
// is one.
284-
unsafe {
285-
let _g = LOCK.lock();
286-
match FILTER as uint {
287-
0 => {}
288-
1 => panic!("cannot log after main thread has exited"),
289-
n => {
290-
let filter = mem::transmute::<_, &Regex>(n);
291-
if !filter.is_match(args.to_string().as_slice()) {
292-
return
293-
}
294-
}
295-
}
282+
match unsafe { FILTER.as_ref() } {
283+
Some(filter) if !filter.is_match(args.to_string()[]) => return,
284+
_ => {}
296285
}
297286

298287
// Completely remove the local logger from TLS in case anyone attempts to
@@ -374,15 +363,9 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
374363

375364
// This assertion should never get tripped unless we're in an at_exit
376365
// handler after logging has been torn down and a logging attempt was made.
366+
assert!(unsafe { !DIRECTIVES.is_null() });
377367

378-
let _g = LOCK.lock();
379-
unsafe {
380-
assert!(DIRECTIVES as uint != 0);
381-
assert!(DIRECTIVES as uint != 1,
382-
"cannot log after the main thread has exited");
383-
384-
enabled(level, module, (*DIRECTIVES).iter())
385-
}
368+
enabled(level, module, unsafe { (*DIRECTIVES).iter() })
386369
}
387370

388371
fn enabled(level: u32,
@@ -438,15 +421,14 @@ fn init() {
438421

439422
// Schedule the cleanup for the globals for when the runtime exits.
440423
rt::at_exit(move |:| {
441-
let _g = LOCK.lock();
442424
assert!(!DIRECTIVES.is_null());
443425
let _directives: Box<Vec<directive::LogDirective>> =
444426
mem::transmute(DIRECTIVES);
445-
DIRECTIVES = 1 as *const Vec<directive::LogDirective>;
427+
DIRECTIVES = 0 as *const Vec<directive::LogDirective>;
446428

447429
if !FILTER.is_null() {
448430
let _filter: Box<Regex> = mem::transmute(FILTER);
449-
FILTER = 1 as *const _;
431+
FILTER = 0 as *const _;
450432
}
451433
});
452434
}

src/libstd/io/stdio.rs

+24-19
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,29 @@
2626
//! ```
2727
2828
use self::StdSource::*;
29-
use prelude::*;
3029

30+
use boxed::Box;
3131
use cell::RefCell;
32+
use clone::Clone;
3233
use failure::LOCAL_STDERR;
3334
use fmt;
34-
use io::{IoResult, IoError, OtherIoError};
35-
use io::{standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
35+
use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer,
36+
standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
37+
use kinds::{Sync, Send};
3638
use libc;
3739
use mem;
40+
use option::Option;
41+
use option::Option::{Some, None};
42+
use ops::{Deref, DerefMut, FnOnce};
43+
use result::Result::{Ok, Err};
3844
use rt;
45+
use slice::SliceExt;
46+
use str::StrExt;
47+
use string::String;
3948
use sys::{fs, tty};
40-
use sync::{Arc, Mutex, MutexGuard, StaticMutex, MUTEX_INIT};
49+
use sync::{Arc, Mutex, MutexGuard, Once, ONCE_INIT};
4150
use uint;
51+
use vec::Vec;
4252

4353
// And so begins the tale of acquiring a uv handle to a stdio stream on all
4454
// platforms in all situations. Our story begins by splitting the world into two
@@ -205,15 +215,14 @@ impl Reader for StdinReader {
205215
pub fn stdin() -> StdinReader {
206216
// We're following the same strategy as kimundi's lazy_static library
207217
static mut STDIN: *const StdinReader = 0 as *const StdinReader;
208-
static LOCK: StaticMutex = MUTEX_INIT;
218+
static ONCE: Once = ONCE_INIT;
209219

210220
unsafe {
211-
let _g = LOCK.lock();
212-
if STDIN as uint == 0 {
213-
// The default buffer capacity is 64k, but apparently windows
214-
// doesn't like 64k reads on stdin. See #13304 for details, but the
215-
// idea is that on windows we use a slightly smaller buffer that's
216-
// been seen to be acceptable.
221+
ONCE.doit(|| {
222+
// The default buffer capacity is 64k, but apparently windows doesn't like
223+
// 64k reads on stdin. See #13304 for details, but the idea is that on
224+
// windows we use a slightly smaller buffer that's been seen to be
225+
// acceptable.
217226
let stdin = if cfg!(windows) {
218227
BufferedReader::with_capacity(8 * 1024, stdin_raw())
219228
} else {
@@ -226,15 +235,11 @@ pub fn stdin() -> StdinReader {
226235

227236
// Make sure to free it at exit
228237
rt::at_exit(|| {
229-
let g = LOCK.lock();
230-
let stdin = STDIN;
231-
STDIN = 1 as *const _;
232-
drop(g);
233-
mem::transmute::<_, Box<StdinReader>>(stdin);
238+
mem::transmute::<_, Box<StdinReader>>(STDIN);
239+
STDIN = 0 as *const _;
234240
});
235-
} else if STDIN as uint == 1 {
236-
panic!("accessing stdin after the main thread has exited")
237-
}
241+
});
242+
238243
(*STDIN).clone()
239244
}
240245
}

src/libstd/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,13 @@ pub mod thread;
229229
pub mod sync;
230230
pub mod comm;
231231

232-
#[path = "sys/common/mod.rs"] mod sys_common;
233-
234232
#[cfg(unix)]
235233
#[path = "sys/unix/mod.rs"] mod sys;
236234
#[cfg(windows)]
237235
#[path = "sys/windows/mod.rs"] mod sys;
238236

237+
#[path = "sys/common/mod.rs"] mod sys_common;
238+
239239
pub mod rt;
240240
mod failure;
241241

src/libstd/rt/at_exit_imp.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ type Queue = Vec<Thunk>;
2929
static LOCK: Mutex = MUTEX_INIT;
3030
static mut QUEUE: *mut Queue = 0 as *mut Queue;
3131

32-
const DTOR_RUN_ITERS: uint = 10;
33-
3432
unsafe fn init() {
3533
if QUEUE.is_null() {
3634
let state: Box<Queue> = box Vec::new();
@@ -51,7 +49,7 @@ pub fn cleanup() {
5149
unsafe {
5250
LOCK.lock();
5351
let queue = QUEUE;
54-
QUEUE = 1u as *mut _;
52+
QUEUE = 1 as *mut _;
5553
LOCK.unlock();
5654

5755
// make sure we're not recursively cleaning up

src/libstd/rt/mod.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
9292
// but we just do this to name the main thread and to give it correct
9393
// info about the stack bounds.
9494
let thread: Thread = NewThread::new(Some("<main>".to_string()));
95-
thread_info::set(sys::thread::guard::main(), thread);
95+
thread_info::set((my_stack_bottom, my_stack_top),
96+
sys::thread::guard::main(),
97+
thread);
9698

9799
// By default, some platforms will send a *signal* when a EPIPE error
98100
// would otherwise be delivered. This runtime doesn't install a SIGPIPE
@@ -131,14 +133,20 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
131133
}
132134
}
133135

134-
/// Enqueues a procedure to run when the main thread exits.
136+
/// Enqueues a procedure to run when the runtime is cleaned up
137+
///
138+
/// The procedure passed to this function will be executed as part of the
139+
/// runtime cleanup phase. For normal rust programs, this means that it will run
140+
/// after all other threads have exited.
141+
///
142+
/// The procedure is *not* executed with a local `Thread` available to it, so
143+
/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
144+
/// This is meant for "bare bones" usage to clean up runtime details, this is
145+
/// not meant as a general-purpose "let's clean everything up" function.
135146
///
136147
/// It is forbidden for procedures to register more `at_exit` handlers when they
137148
/// are running, and doing so will lead to a process abort.
138-
///
139-
/// Note that other threads may still be running when `at_exit` routines start
140-
/// running.
141-
pub fn at_exit<F: FnOnce() + Send>(f: F) {
149+
pub fn at_exit<F:FnOnce()+Send>(f: F) {
142150
at_exit_imp::push(Thunk::new(f));
143151
}
144152

@@ -154,5 +162,8 @@ pub fn at_exit<F: FnOnce() + Send>(f: F) {
154162
pub unsafe fn cleanup() {
155163
args::cleanup();
156164
sys::stack_overflow::cleanup();
157-
at_exit_imp::cleanup();
165+
// FIXME: (#20012): the resources being cleaned up by at_exit
166+
// currently are not prepared for cleanup to happen asynchronously
167+
// with detached threads using the resources; for now, we leak.
168+
// at_exit_imp::cleanup();
158169
}

src/libstd/rt/unwind.rs

+4-13
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use intrinsics;
6868
use libc::c_void;
6969
use mem;
7070
use sync::atomic;
71-
use sys_common::mutex::{Mutex, MUTEX_INIT};
71+
use sync::{Once, ONCE_INIT};
7272

7373
use rt::libunwind as uw;
7474

@@ -540,20 +540,11 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) ->
540540
/// Doing this split took the LLVM IR line counts of `fn main() { panic!()
541541
/// }` from ~1900/3700 (-O/no opts) to 180/590.
542542
#[inline(never)] #[cold] // this is the slow path, please never inline this
543-
fn begin_unwind_inner(msg: Box<Any + Send>,
544-
file_line: &(&'static str, uint)) -> ! {
543+
fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) -> ! {
545544
// Make sure the default failure handler is registered before we look at the
546545
// callbacks.
547-
unsafe {
548-
static LOCK: Mutex = MUTEX_INIT;
549-
static mut INIT: bool = false;
550-
LOCK.lock();
551-
if !INIT {
552-
register(failure::on_fail);
553-
INIT = true;
554-
}
555-
LOCK.unlock();
556-
}
546+
static INIT: Once = ONCE_INIT;
547+
INIT.doit(|| unsafe { register(failure::on_fail); });
557548

558549
// First, invoke call the user-defined callbacks triggered on thread panic.
559550
//

src/libstd/sys/common/helper_thread.rs

+5-26
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
//! can be created in the future and there must be no active timers at that
2121
//! time.
2222
23-
#![macro_escape]
24-
2523
use prelude::*;
2624

2725
use cell::UnsafeCell;
@@ -70,17 +68,6 @@ struct RaceBox(helper_signal::signal);
7068
unsafe impl Send for RaceBox {}
7169
unsafe impl Sync for RaceBox {}
7270

73-
macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
74-
static $name: Helper<$m> = Helper {
75-
lock: ::sync::MUTEX_INIT,
76-
cond: ::sync::CONDVAR_INIT,
77-
chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
78-
signal: ::cell::UnsafeCell { value: 0 },
79-
initialized: ::cell::UnsafeCell { value: false },
80-
shutdown: ::cell::UnsafeCell { value: false },
81-
};
82-
) }
83-
8471
impl<M: Send> Helper<M> {
8572
/// Lazily boots a helper thread, becoming a no-op if the helper has already
8673
/// been spawned.
@@ -97,7 +84,7 @@ impl<M: Send> Helper<M> {
9784
{
9885
unsafe {
9986
let _guard = self.lock.lock().unwrap();
100-
if *self.chan.get() as uint == 0 {
87+
if !*self.initialized.get() {
10188
let (tx, rx) = channel();
10289
*self.chan.get() = mem::transmute(box tx);
10390
let (receive, send) = helper_signal::new();
@@ -106,17 +93,15 @@ impl<M: Send> Helper<M> {
10693
let receive = RaceBox(receive);
10794

10895
let t = f();
109-
Thread::spawn(move || {
96+
Thread::spawn(move |:| {
11097
helper(receive.0, rx, t);
11198
let _g = self.lock.lock().unwrap();
11299
*self.shutdown.get() = true;
113100
self.cond.notify_one()
114101
}).detach();
115102

116-
rt::at_exit(move || { self.shutdown() });
103+
rt::at_exit(move|:| { self.shutdown() });
117104
*self.initialized.get() = true;
118-
} else if *self.chan.get() as uint == 1 {
119-
panic!("cannot continue usage after shutdown");
120105
}
121106
}
122107
}
@@ -131,9 +116,7 @@ impl<M: Send> Helper<M> {
131116
// Must send and *then* signal to ensure that the child receives the
132117
// message. Otherwise it could wake up and go to sleep before we
133118
// send the message.
134-
assert!(*self.chan.get() as uint != 0);
135-
assert!(*self.chan.get() as uint != 1,
136-
"cannot continue usage after shutdown");
119+
assert!(!self.chan.get().is_null());
137120
(**self.chan.get()).send(msg);
138121
helper_signal::signal(*self.signal.get() as helper_signal::signal);
139122
}
@@ -146,13 +129,9 @@ impl<M: Send> Helper<M> {
146129
// returns.
147130
let mut guard = self.lock.lock().unwrap();
148131

149-
let ptr = *self.chan.get();
150-
if ptr as uint == 1 {
151-
panic!("cannot continue usage after shutdown");
152-
}
153132
// Close the channel by destroying it
154133
let chan: Box<Sender<M>> = mem::transmute(*self.chan.get());
155-
*self.chan.get() = 1 as *mut Sender<M>;
134+
*self.chan.get() = 0 as *mut Sender<M>;
156135
drop(chan);
157136
helper_signal::signal(*self.signal.get() as helper_signal::signal);
158137

src/libstd/sys/common/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
#![allow(missing_docs)]
12-
#![macro_escape]
12+
#![allow(dead_code)]
1313

1414
use io::{mod, IoError, IoResult};
1515
use prelude::*;

src/libstd/sys/common/mutex.rs

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ impl Mutex {
2929
/// Behavior is undefined if the mutex is moved after the first method is
3030
/// called on the mutex.
3131
#[inline]
32-
#[allow(dead_code)] // sys is not exported yet
3332
pub unsafe fn new() -> Mutex { Mutex(imp::Mutex::new()) }
3433

3534
/// Lock the mutex blocking the current thread until it is available.

src/libstd/sys/common/net.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ use io::{IoResult, IoError};
2323
use sys::{mod, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
2424
wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
2525
decode_error_detailed};
26-
use sync::Mutex;
27-
#[cfg(not(target_os = "linux"))]
28-
use sync::MutexGuard;
26+
use sync::{Mutex, MutexGuard};
2927
use sys_common::{mod, keep_going, short_write, timeout};
3028
use prelude::*;
3129
use cmp;
@@ -613,13 +611,11 @@ impl Drop for Inner {
613611
fn drop(&mut self) { unsafe { close_sock(self.fd); } }
614612
}
615613

616-
#[cfg(not(target_os = "linux"))]
617614
pub struct Guard<'a> {
618615
pub fd: sock_t,
619616
pub guard: MutexGuard<'a, ()>,
620617
}
621618

622-
#[cfg(not(target_os = "linux"))]
623619
#[unsafe_destructor]
624620
impl<'a> Drop for Guard<'a> {
625621
fn drop(&mut self) {

src/libstd/sys/common/rwlock.rs

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ impl RWLock {
2626
/// Usage of an RWLock is undefined if it is moved after its first use (any
2727
/// function calls below).
2828
#[inline]
29-
#[allow(dead_code)] // sys is not exported yet
3029
pub unsafe fn new() -> RWLock { RWLock(imp::RWLock::new()) }
3130

3231
/// Acquire shared access to the underlying lock, blocking the current

0 commit comments

Comments
 (0)