Skip to content

Commit

Permalink
Introduce std::thread
Browse files Browse the repository at this point in the history
Also removes:

* `std::task`
* `std::rt::task`
* `std::rt::thread`

Notes for the new API are in a follow-up commit.

Closes #18000
  • Loading branch information
aturon committed Dec 19, 2014
1 parent 9b03b72 commit cac133c
Show file tree
Hide file tree
Showing 6 changed files with 742 additions and 720 deletions.
4 changes: 2 additions & 2 deletions src/libstd/lib.rs
Expand Up @@ -227,9 +227,9 @@ pub mod time;
pub mod collections;
pub mod hash;

/* Tasks and communication */
/* Threads and communication */

pub mod task;
pub mod thread;
pub mod sync;
pub mod comm;

Expand Down
35 changes: 15 additions & 20 deletions src/libstd/rt/mod.rs
Expand Up @@ -53,7 +53,9 @@ use failure;
use os;
use thunk::Thunk;
use kinds::Send;
use thread::Thread;
use sys_common;
use sys_common::thread::{mod, NewThread};

// Reexport some of our utilities which are expected by other crates.
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
Expand All @@ -73,8 +75,6 @@ pub mod mutex;
pub mod thread;
pub mod exclusive;
pub mod util;
pub mod local;
pub mod task;
pub mod unwind;

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

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

init(argc, argv);
let mut exit_code = None;
let mut main = Some(main);
let mut task = box Task::new(Some((my_stack_bottom, my_stack_top)),
Some(rt::thread::main_guard_page()));
task.name = Some(str::Slice("<main>"));
drop(task.run(|| {

let thread: std::Thread = NewThread::new(Some("<main>".into_string()));
thread_info::set((my_stack_bottom, my_stack_top),
unsafe { sys::thread::guard::main() },
thread);
unwind::try(|| {
unsafe {
sys_common::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
}
(main.take().unwrap()).invoke(());
exit_code = Some(os::get_exit_status());
}).destroy());
});
unsafe { cleanup(); }
// If the exit code wasn't set, then the task block must have panicked.
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
Expand Down Expand Up @@ -207,8 +203,7 @@ pub fn at_exit(f: proc():Send) {
/// undefined behavior.
pub unsafe fn cleanup() {
args::cleanup();
thread::cleanup();
local_ptr::cleanup();
sys::stack_overflow::cleanup();
}

// FIXME: these probably shouldn't be public...
Expand Down
171 changes: 0 additions & 171 deletions src/libstd/rt/thread.rs

This file was deleted.

60 changes: 60 additions & 0 deletions src/libstd/sys/common/thread_info.rs
@@ -0,0 +1,60 @@
// Copyright 2014 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.

struct ThreadInfo {
// This field holds the known bounds of the stack in (lo, hi)
// form. Not all threads necessarily know their precise bounds,
// hence this is optional.
stack_bounds: (uint, uint),
stack_guard: uint,
unwinder: Unwinder,
thread: Thread,
}

thread_local!(static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(None));

impl ThreadInfo {
fn with<R>(f: |&ThreadInfo| -> R) -> R {
THREAD_INFO.with(|c| {
if c.borrow().is_none() {
*c.borrow_mut() = Some(ThreadInfo {
stack_bounds: (0, 0),
stack_guard: 0,
unwinder: Unwinder::new(),
thread: Thread::new(None),
})
}
f(c.borrow().as_ref().unwrap())
})
}
}

pub fn current_thread() -> Thread {
ThreadInfo::with(|info| info.thread.clone())
}

pub fn panicking() -> bool {
ThreadInfo::with(|info| info.unwinder.unwinding())
}

pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) {
THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
THREAD_INFO.with(|c| *c.borrow_mut() = Some(ThreadInfo{
stack_bounds: stack_bounds,
stack_guard: stack_guard,
unwinder: Unwinder::new(),
thread: thread,
}));
}

// a hack to get around privacy restrictions; implemented by `std::thread::Thread`
pub trait NewThread {
fn new(name: Option<String>) -> Self;
}

0 comments on commit cac133c

Please sign in to comment.