std::rt: Change Thread interface to require an explicit join
Makes it more obvious what's going on
This commit is contained in:
parent
7265cc6530
commit
0144c83213
@ -674,10 +674,11 @@ mod test {
|
||||
do run_in_newsched_task {
|
||||
let (port, chan) = oneshot::<int>();
|
||||
let port_cell = Cell::new(port);
|
||||
let _thread = do spawntask_thread {
|
||||
let thread = do spawntask_thread {
|
||||
let _p = port_cell.take();
|
||||
};
|
||||
let _chan = chan;
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -689,13 +690,15 @@ mod test {
|
||||
let (port, chan) = oneshot::<int>();
|
||||
let chan_cell = Cell::new(chan);
|
||||
let port_cell = Cell::new(port);
|
||||
let _thread1 = do spawntask_thread {
|
||||
let thread1 = do spawntask_thread {
|
||||
let _p = port_cell.take();
|
||||
};
|
||||
let _thread2 = do spawntask_thread {
|
||||
let thread2 = do spawntask_thread {
|
||||
let c = chan_cell.take();
|
||||
c.send(1);
|
||||
};
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -707,19 +710,21 @@ mod test {
|
||||
let (port, chan) = oneshot::<int>();
|
||||
let chan_cell = Cell::new(chan);
|
||||
let port_cell = Cell::new(port);
|
||||
let _thread1 = do spawntask_thread {
|
||||
let thread1 = do spawntask_thread {
|
||||
let port_cell = Cell::new(port_cell.take());
|
||||
let res = do spawntask_try {
|
||||
port_cell.take().recv();
|
||||
};
|
||||
assert!(res.is_err());
|
||||
};
|
||||
let _thread2 = do spawntask_thread {
|
||||
let thread2 = do spawntask_thread {
|
||||
let chan_cell = Cell::new(chan_cell.take());
|
||||
do spawntask {
|
||||
chan_cell.take();
|
||||
}
|
||||
};
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -731,12 +736,14 @@ mod test {
|
||||
let (port, chan) = oneshot::<~int>();
|
||||
let chan_cell = Cell::new(chan);
|
||||
let port_cell = Cell::new(port);
|
||||
let _thread1 = do spawntask_thread {
|
||||
let thread1 = do spawntask_thread {
|
||||
chan_cell.take().send(~10);
|
||||
};
|
||||
let _thread2 = do spawntask_thread {
|
||||
let thread2 = do spawntask_thread {
|
||||
assert!(port_cell.take().recv() == ~10);
|
||||
};
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -343,7 +343,9 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
|
||||
}
|
||||
|
||||
// Wait for schedulers
|
||||
{ let _threads = threads; }
|
||||
for threads.consume_iter().advance() |thread| {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
// Return the exit code
|
||||
unsafe {
|
||||
|
@ -901,10 +901,8 @@ mod test {
|
||||
sched.run();
|
||||
};
|
||||
|
||||
// wait for the end
|
||||
let _thread1 = normal_thread;
|
||||
let _thread2 = special_thread;
|
||||
|
||||
normal_thread.join();
|
||||
special_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1074,16 +1072,19 @@ mod test {
|
||||
sched2.enqueue_task(task2);
|
||||
|
||||
let sched1_cell = Cell::new(sched1);
|
||||
let _thread1 = do Thread::start {
|
||||
let thread1 = do Thread::start {
|
||||
let sched1 = sched1_cell.take();
|
||||
sched1.run();
|
||||
};
|
||||
|
||||
let sched2_cell = Cell::new(sched2);
|
||||
let _thread2 = do Thread::start {
|
||||
let thread2 = do Thread::start {
|
||||
let sched2 = sched2_cell.take();
|
||||
sched2.run();
|
||||
};
|
||||
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,9 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
|
||||
}
|
||||
|
||||
// Wait for schedulers
|
||||
let _threads = threads;
|
||||
for threads.consume_iter().advance() |thread| {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ type raw_thread = libc::c_void;
|
||||
|
||||
pub struct Thread {
|
||||
main: ~fn(),
|
||||
raw_thread: *raw_thread
|
||||
raw_thread: *raw_thread,
|
||||
joined: bool
|
||||
}
|
||||
|
||||
impl Thread {
|
||||
@ -27,18 +28,28 @@ impl Thread {
|
||||
let raw = substart(&main);
|
||||
Thread {
|
||||
main: main,
|
||||
raw_thread: raw
|
||||
raw_thread: raw,
|
||||
joined: false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn join(self) {
|
||||
assert!(!self.joined);
|
||||
let mut this = self;
|
||||
unsafe { rust_raw_thread_join(this.raw_thread); }
|
||||
this.joined = true;
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Thread {
|
||||
fn drop(&self) {
|
||||
unsafe { rust_raw_thread_join_delete(self.raw_thread) }
|
||||
assert!(self.joined);
|
||||
unsafe { rust_raw_thread_delete(self.raw_thread) }
|
||||
}
|
||||
}
|
||||
|
||||
extern {
|
||||
pub unsafe fn rust_raw_thread_start(f: &(~fn())) -> *raw_thread;
|
||||
pub unsafe fn rust_raw_thread_join_delete(thread: *raw_thread);
|
||||
pub unsafe fn rust_raw_thread_join(thread: *raw_thread);
|
||||
pub unsafe fn rust_raw_thread_delete(thread: *raw_thread);
|
||||
}
|
||||
|
@ -94,12 +94,13 @@ mod test {
|
||||
let mut loop_ = Loop::new();
|
||||
let watcher = AsyncWatcher::new(&mut loop_, |w, _| w.close(||()) );
|
||||
let watcher_cell = Cell::new(watcher);
|
||||
let _thread = do Thread::start {
|
||||
let thread = do Thread::start {
|
||||
let mut watcher = watcher_cell.take();
|
||||
watcher.send();
|
||||
};
|
||||
loop_.run();
|
||||
loop_.close();
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -715,7 +715,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
let _client_thread = do Thread::start {
|
||||
let client_thread = do Thread::start {
|
||||
rtdebug!("starting client thread");
|
||||
let mut loop_ = Loop::new();
|
||||
let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
|
||||
@ -739,6 +739,7 @@ mod test {
|
||||
let mut loop_ = loop_;
|
||||
loop_.run();
|
||||
loop_.close();
|
||||
client_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
@ -790,7 +791,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
let _client_thread = do Thread::start {
|
||||
let client_thread = do Thread::start {
|
||||
rtdebug!("starting client thread");
|
||||
let mut loop_ = Loop::new();
|
||||
let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
|
||||
@ -814,6 +815,7 @@ mod test {
|
||||
let mut loop_ = loop_;
|
||||
loop_.run();
|
||||
loop_.close();
|
||||
client_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,7 +857,7 @@ mod test {
|
||||
server.close(||{});
|
||||
}
|
||||
|
||||
do Thread::start {
|
||||
let thread = do Thread::start {
|
||||
let mut loop_ = Loop::new();
|
||||
let mut client = UdpWatcher::new(&loop_);
|
||||
assert!(client.bind(client_addr).is_ok());
|
||||
@ -873,6 +875,7 @@ mod test {
|
||||
|
||||
loop_.run();
|
||||
loop_.close();
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
@ -914,7 +917,7 @@ mod test {
|
||||
server.close(||{});
|
||||
}
|
||||
|
||||
do Thread::start {
|
||||
let thread = do Thread::start {
|
||||
let mut loop_ = Loop::new();
|
||||
let mut client = UdpWatcher::new(&loop_);
|
||||
assert!(client.bind(client_addr).is_ok());
|
||||
@ -932,6 +935,7 @@ mod test {
|
||||
|
||||
loop_.run();
|
||||
loop_.close();
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,11 +222,12 @@ mod test_remote {
|
||||
};
|
||||
remote_cell.put_back(remote);
|
||||
}
|
||||
let _thread = do Thread::start {
|
||||
let thread = do Thread::start {
|
||||
remote_cell.take().fire();
|
||||
};
|
||||
|
||||
assert!(tube.recv() == 1);
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
use comm::{GenericChan, GenericPort};
|
||||
use comm;
|
||||
use libc;
|
||||
use prelude::*;
|
||||
use task;
|
||||
|
||||
@ -37,18 +36,16 @@ The executing thread has no access to a task pointer and will be using
|
||||
a normal large stack.
|
||||
*/
|
||||
pub fn run_in_bare_thread(f: ~fn()) {
|
||||
use cell::Cell;
|
||||
use rt::thread::Thread;
|
||||
|
||||
let f_cell = Cell::new(f);
|
||||
let (port, chan) = comm::stream();
|
||||
// FIXME #4525: Unfortunate that this creates an extra scheduler but it's
|
||||
// necessary since rust_raw_thread_join_delete is blocking
|
||||
// necessary since rust_raw_thread_join is blocking
|
||||
do task::spawn_sched(task::SingleThreaded) {
|
||||
unsafe {
|
||||
let closure: &fn() = || {
|
||||
f()
|
||||
};
|
||||
let thread = rust_raw_thread_start(&closure);
|
||||
rust_raw_thread_join_delete(thread);
|
||||
chan.send(());
|
||||
}
|
||||
Thread::start(f_cell.take()).join();
|
||||
chan.send(());
|
||||
}
|
||||
port.recv();
|
||||
}
|
||||
@ -70,14 +67,6 @@ fn test_run_in_bare_thread_exchange() {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)] // runtime type
|
||||
pub type raw_thread = libc::c_void;
|
||||
|
||||
extern {
|
||||
fn rust_raw_thread_start(f: &(&fn())) -> *raw_thread;
|
||||
fn rust_raw_thread_join_delete(thread: *raw_thread);
|
||||
}
|
||||
|
||||
|
||||
/// Changes the current working directory to the specified
|
||||
/// path while acquiring a global lock, then calls `action`.
|
||||
|
@ -751,9 +751,14 @@ rust_raw_thread_start(fn_env_pair *fn) {
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
rust_raw_thread_join_delete(raw_thread *thread) {
|
||||
rust_raw_thread_join(raw_thread *thread) {
|
||||
assert(thread);
|
||||
thread->join();
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
rust_raw_thread_delete(raw_thread *thread) {
|
||||
assert(thread);
|
||||
delete thread;
|
||||
}
|
||||
|
||||
|
@ -211,7 +211,8 @@ linenoiseHistorySetMaxLen
|
||||
linenoiseHistorySave
|
||||
linenoiseHistoryLoad
|
||||
rust_raw_thread_start
|
||||
rust_raw_thread_join_delete
|
||||
rust_raw_thread_join
|
||||
rust_raw_thread_delete
|
||||
rust_get_rt_tls_key
|
||||
swap_registers
|
||||
rust_readdir
|
||||
|
Loading…
Reference in New Issue
Block a user