Skip to content

Commit cac133c

Browse files
committed
Introduce std::thread
Also removes: * `std::task` * `std::rt::task` * `std::rt::thread` Notes for the new API are in a follow-up commit. Closes rust-lang#18000
1 parent 9b03b72 commit cac133c

File tree

6 files changed

+742
-720
lines changed

6 files changed

+742
-720
lines changed

src/libstd/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ pub mod time;
227227
pub mod collections;
228228
pub mod hash;
229229

230-
/* Tasks and communication */
230+
/* Threads and communication */
231231

232-
pub mod task;
232+
pub mod thread;
233233
pub mod sync;
234234
pub mod comm;
235235

src/libstd/rt/mod.rs

+15-20
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ use failure;
5353
use os;
5454
use thunk::Thunk;
5555
use kinds::Send;
56+
use thread::Thread;
5657
use sys_common;
58+
use sys_common::thread::{mod, NewThread};
5759

5860
// Reexport some of our utilities which are expected by other crates.
5961
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
@@ -73,8 +75,6 @@ pub mod mutex;
7375
pub mod thread;
7476
pub mod exclusive;
7577
pub mod util;
76-
pub mod local;
77-
pub mod task;
7878
pub mod unwind;
7979

8080
mod args;
@@ -98,8 +98,8 @@ pub fn init(argc: int, argv: *const *const u8) {
9898
// Need to propagate the unsafety to `start`.
9999
unsafe {
100100
args::init(argc, argv);
101-
local_ptr::init();
102-
thread::init();
101+
sys::thread::guard::init();
102+
sys::stack_overflow::init();
103103
unwind::register(failure::on_fail);
104104
}
105105
}
@@ -125,9 +125,6 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
125125
/// This procedure is guaranteed to run on the thread calling this function, but
126126
/// the stack bounds for this rust task will *not* be set. Care must be taken
127127
/// for this function to not overflow its stack.
128-
///
129-
/// This function will only return once *all* native threads in the system have
130-
/// exited.
131128
pub fn start(argc: int, argv: *const *const u8, main: Thunk) -> int {
132129
use prelude::*;
133130
use rt;
@@ -143,11 +140,9 @@ pub fn start(argc: int, argv: *const *const u8, main: Thunk) -> int {
143140
// frames above our current position.
144141
let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
145142

146-
// When using libgreen, one of the first things that we do is to turn off
147-
// the SIGPIPE signal (set it to ignore). By default, some platforms will
148-
// send a *signal* when a EPIPE error would otherwise be delivered. This
149-
// runtime doesn't install a SIGPIPE handler, causing it to kill the
150-
// program, which isn't exactly what we want!
143+
// By default, some platforms will send a *signal* when a EPIPE error would
144+
// otherwise be delivered. This runtime doesn't install a SIGPIPE handler,
145+
// causing it to kill the program, which isn't exactly what we want!
151146
//
152147
// Hence, we set SIGPIPE to ignore when the program starts up in order to
153148
// prevent this problem.
@@ -163,17 +158,18 @@ pub fn start(argc: int, argv: *const *const u8, main: Thunk) -> int {
163158

164159
init(argc, argv);
165160
let mut exit_code = None;
166-
let mut main = Some(main);
167-
let mut task = box Task::new(Some((my_stack_bottom, my_stack_top)),
168-
Some(rt::thread::main_guard_page()));
169-
task.name = Some(str::Slice("<main>"));
170-
drop(task.run(|| {
161+
162+
let thread: std::Thread = NewThread::new(Some("<main>".into_string()));
163+
thread_info::set((my_stack_bottom, my_stack_top),
164+
unsafe { sys::thread::guard::main() },
165+
thread);
166+
unwind::try(|| {
171167
unsafe {
172168
sys_common::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
173169
}
174170
(main.take().unwrap()).invoke(());
175171
exit_code = Some(os::get_exit_status());
176-
}).destroy());
172+
});
177173
unsafe { cleanup(); }
178174
// If the exit code wasn't set, then the task block must have panicked.
179175
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
@@ -207,8 +203,7 @@ pub fn at_exit(f: proc():Send) {
207203
/// undefined behavior.
208204
pub unsafe fn cleanup() {
209205
args::cleanup();
210-
thread::cleanup();
211-
local_ptr::cleanup();
206+
sys::stack_overflow::cleanup();
212207
}
213208

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

src/libstd/rt/thread.rs

-171
This file was deleted.

src/libstd/sys/common/thread_info.rs

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2014 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.
4+
//
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.
10+
11+
struct ThreadInfo {
12+
// This field holds the known bounds of the stack in (lo, hi)
13+
// form. Not all threads necessarily know their precise bounds,
14+
// hence this is optional.
15+
stack_bounds: (uint, uint),
16+
stack_guard: uint,
17+
unwinder: Unwinder,
18+
thread: Thread,
19+
}
20+
21+
thread_local!(static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(None));
22+
23+
impl ThreadInfo {
24+
fn with<R>(f: |&ThreadInfo| -> R) -> R {
25+
THREAD_INFO.with(|c| {
26+
if c.borrow().is_none() {
27+
*c.borrow_mut() = Some(ThreadInfo {
28+
stack_bounds: (0, 0),
29+
stack_guard: 0,
30+
unwinder: Unwinder::new(),
31+
thread: Thread::new(None),
32+
})
33+
}
34+
f(c.borrow().as_ref().unwrap())
35+
})
36+
}
37+
}
38+
39+
pub fn current_thread() -> Thread {
40+
ThreadInfo::with(|info| info.thread.clone())
41+
}
42+
43+
pub fn panicking() -> bool {
44+
ThreadInfo::with(|info| info.unwinder.unwinding())
45+
}
46+
47+
pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) {
48+
THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
49+
THREAD_INFO.with(|c| *c.borrow_mut() = Some(ThreadInfo{
50+
stack_bounds: stack_bounds,
51+
stack_guard: stack_guard,
52+
unwinder: Unwinder::new(),
53+
thread: thread,
54+
}));
55+
}
56+
57+
// a hack to get around privacy restrictions; implemented by `std::thread::Thread`
58+
pub trait NewThread {
59+
fn new(name: Option<String>) -> Self;
60+
}

0 commit comments

Comments
 (0)