mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-22 04:34:51 +00:00
Using move-mode for spawn thunks to avoid race conditions.
This commit is contained in:
parent
1d7ca9c189
commit
94260fb91d
@ -75,21 +75,22 @@ fn set_min_stack(stack_size : uint) {
|
||||
rustrt::set_min_stack(stack_size);
|
||||
}
|
||||
|
||||
fn _spawn(thunk : fn() -> ()) -> task {
|
||||
fn _spawn(thunk : -fn() -> ()) -> task {
|
||||
spawn(thunk)
|
||||
}
|
||||
|
||||
fn spawn(thunk : fn() -> ()) -> task {
|
||||
fn spawn(thunk : -fn() -> ()) -> task {
|
||||
spawn_inner(thunk, none)
|
||||
}
|
||||
|
||||
fn spawn_notify(thunk : fn() -> (), notify : _chan<task_notification>)
|
||||
fn spawn_notify(thunk : -fn() -> (), notify : _chan<task_notification>)
|
||||
-> task {
|
||||
spawn_inner(thunk, some(notify))
|
||||
}
|
||||
|
||||
// FIXME: make this a fn~ once those are supported.
|
||||
fn spawn_inner(thunk : fn() -> (), notify : option<_chan<task_notification>>)
|
||||
fn spawn_inner(thunk : -fn() -> (),
|
||||
notify : option<_chan<task_notification>>)
|
||||
-> task_id {
|
||||
let id = rustrt::new_task();
|
||||
|
||||
|
@ -336,13 +336,16 @@ fn run_test(test: &test_desc, to_task: &test_to_task) -> test_future {
|
||||
// we've got to treat our test functions as unsafe pointers. This function
|
||||
// only works with functions that don't contain closures.
|
||||
fn default_test_to_task(f: &fn()) -> task_id {
|
||||
/*
|
||||
fn run_task(fptr: *mutable fn() ) {
|
||||
configure_test_task();
|
||||
// Run the test
|
||||
(*fptr)()
|
||||
}
|
||||
let fptr = ptr::addr_of(f);
|
||||
ret task::_spawn(bind run_task(fptr));
|
||||
*/
|
||||
//ret task::_spawn(bind run_task(fptr));
|
||||
task::spawn(f)
|
||||
}
|
||||
|
||||
// Call from within a test task to make sure it's set up correctly
|
||||
|
@ -7,7 +7,8 @@ import std::str;
|
||||
fn f(n: uint) {
|
||||
let i = 0u;
|
||||
while i < n {
|
||||
task::join_id(task::_spawn(bind g()));
|
||||
let thunk = g;
|
||||
task::join_id(task::spawn(thunk));
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
@ -23,7 +24,7 @@ fn main(args: [str]) {
|
||||
};
|
||||
let i = 0u;
|
||||
while i < n {
|
||||
task::_spawn(bind f(n));
|
||||
task::spawn(bind f(n));
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ mod map_reduce {
|
||||
fn start_mappers(ctrl: _chan<ctrl_proto>, inputs: &[str]) -> [task_id] {
|
||||
let tasks = ~[];
|
||||
for i: str in inputs {
|
||||
tasks += ~[task::_spawn(bind map_task(ctrl, i))];
|
||||
tasks += ~[task::spawn(bind map_task(ctrl, i))];
|
||||
}
|
||||
ret tasks;
|
||||
}
|
||||
@ -179,7 +179,7 @@ mod map_reduce {
|
||||
// log_err "creating new reducer for " + k;
|
||||
let p = mk_port();
|
||||
tasks +=
|
||||
~[task::_spawn(bind reduce_task(k, p.mk_chan()))];
|
||||
~[task::spawn(bind reduce_task(k, p.mk_chan()))];
|
||||
c = p.recv();
|
||||
reducers.insert(k, c);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ fn child() { assert (1 == 2); }
|
||||
|
||||
fn main() {
|
||||
let p = mk_port::<int>();
|
||||
task::_spawn(bind child());
|
||||
let f = child;
|
||||
task::_spawn(f);
|
||||
let x = p.recv();
|
||||
}
|
||||
|
@ -85,8 +85,9 @@ fn test_ptr() {
|
||||
|
||||
fn test_task() {
|
||||
fn f() { }
|
||||
let t1 = task::_spawn(bind f());
|
||||
let t2 = task::_spawn(bind f());
|
||||
let f1 = f, f2 = f;
|
||||
let t1 = task::spawn(f1);
|
||||
let t2 = task::spawn(f2);
|
||||
|
||||
assert t1 == t1;
|
||||
assert t1 != t2;
|
||||
|
@ -13,4 +13,7 @@ fn yield_wrap() {
|
||||
rustrt::task_yield();
|
||||
}
|
||||
|
||||
fn main() { task::_spawn(bind yield_wrap()); }
|
||||
fn main() {
|
||||
let f = yield_wrap;
|
||||
task::_spawn(f);
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ use std;
|
||||
import std::task::*;
|
||||
|
||||
fn main() {
|
||||
let other = _spawn(bind child());
|
||||
let f = child;
|
||||
let other = _spawn(f);
|
||||
log_err "1";
|
||||
yield();
|
||||
join_id(other);
|
||||
|
@ -1,10 +1,15 @@
|
||||
use std;
|
||||
|
||||
import std::task::_spawn;
|
||||
import std::task::spawn;
|
||||
import std::task::join_id;
|
||||
|
||||
fn main() { test00(); }
|
||||
|
||||
fn start() { log "Started / Finished task."; }
|
||||
|
||||
fn test00() { let t = _spawn(bind start()); join_id(t); log "Completing."; }
|
||||
fn test00() {
|
||||
let f = start;
|
||||
let t = spawn(f);
|
||||
join_id(t);
|
||||
log "Completing.";
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ fn test00() {
|
||||
let tasks = [];
|
||||
while i < number_of_tasks {
|
||||
i = i + 1;
|
||||
tasks += [task::_spawn(bind test00_start(ch, i, number_of_messages))];
|
||||
tasks += [task::spawn(bind test00_start(ch, i, number_of_messages))];
|
||||
}
|
||||
|
||||
let sum: int = 0;
|
||||
@ -96,7 +96,11 @@ fn test04_start() {
|
||||
fn test04() {
|
||||
log "Spawning lots of tasks.";
|
||||
let i: int = 4;
|
||||
while i > 0 { i = i - 1; task::_spawn(bind test04_start()); }
|
||||
while i > 0 {
|
||||
i = i - 1;
|
||||
let f = test04_start;
|
||||
task::spawn(f);
|
||||
}
|
||||
log "Finishing up.";
|
||||
}
|
||||
|
||||
@ -111,7 +115,7 @@ fn test05_start(ch: _chan<int>) {
|
||||
fn test05() {
|
||||
let po = comm::mk_port();
|
||||
let ch = po.mk_chan();
|
||||
task::_spawn(bind test05_start(ch));
|
||||
task::spawn(bind test05_start(ch));
|
||||
let value: int;
|
||||
value = po.recv();
|
||||
value = po.recv();
|
||||
@ -134,7 +138,7 @@ fn test06() {
|
||||
|
||||
let tasks = [];
|
||||
while i < number_of_tasks {
|
||||
i = i + 1; tasks += [task::_spawn(bind test06_start(i))]; }
|
||||
i = i + 1; tasks += [task::spawn(bind test06_start(i))]; }
|
||||
|
||||
|
||||
for t: task_id in tasks { task::join_id(t); }
|
||||
|
@ -14,8 +14,9 @@ fn main() {
|
||||
let t1;
|
||||
let t2;
|
||||
|
||||
t1 = task::_spawn(bind child());
|
||||
t2 = task::_spawn(bind child());
|
||||
let c1 = child, c2 = child;
|
||||
t1 = task::_spawn(c1);
|
||||
t2 = task::_spawn(c2);
|
||||
|
||||
assert (t1 == t1);
|
||||
assert (t1 != t2);
|
||||
|
@ -24,12 +24,14 @@ fn supervisor() {
|
||||
// Unsupervise this task so the process doesn't return a failure status as
|
||||
// a result of the main task being killed.
|
||||
task::unsupervise();
|
||||
let t = task::_spawn(bind supervised());
|
||||
let f = supervised;
|
||||
let t = task::_spawn(supervised);
|
||||
task::join_id(t);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let dom2 = task::_spawn(bind supervisor());
|
||||
let f = supervisor;
|
||||
let dom2 = task::_spawn(f);
|
||||
task::join_id(dom2);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,8 @@ import std::task;
|
||||
import std::task::*;
|
||||
|
||||
fn main() {
|
||||
let other = task::_spawn(bind child());
|
||||
let f = child;
|
||||
let other = task::spawn(f);
|
||||
log_err "1";
|
||||
yield();
|
||||
log_err "2";
|
||||
|
@ -4,7 +4,8 @@ import std::task;
|
||||
import std::task::*;
|
||||
|
||||
fn main() {
|
||||
let other = task::_spawn(bind child());
|
||||
let c = child;
|
||||
let other = task::spawn(c);
|
||||
log_err "1"; yield();
|
||||
join_id(other);
|
||||
}
|
||||
|
@ -4,4 +4,4 @@ use std;
|
||||
fn main() {
|
||||
let i: int = 0;
|
||||
while i < 100 { i = i + 1; log_err i; std::task::yield(); }
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,8 @@ fn test_sleep() { task::sleep(1000000u); }
|
||||
#[test]
|
||||
fn test_unsupervise() {
|
||||
fn f() { task::unsupervise(); fail; }
|
||||
task::_spawn(bind f());
|
||||
let foo = f;
|
||||
task::_spawn(foo);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -30,7 +31,8 @@ fn test_join() {
|
||||
#[test]
|
||||
fn test_lib_spawn() {
|
||||
fn foo() { log_err "Hello, World!"; }
|
||||
task::_spawn(foo);
|
||||
let f = foo;
|
||||
task::_spawn(f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -44,7 +46,8 @@ fn test_join_chan() {
|
||||
fn winner() { }
|
||||
|
||||
let p = comm::mk_port::<task::task_notification>();
|
||||
task::spawn_notify(bind winner(), p.mk_chan());
|
||||
let f = winner;
|
||||
task::spawn_notify(f, p.mk_chan());
|
||||
let s = p.recv();
|
||||
log_err "received task status message";
|
||||
log_err s;
|
||||
@ -59,7 +62,8 @@ fn test_join_chan_fail() {
|
||||
fn failer() { task::unsupervise(); fail }
|
||||
|
||||
let p = comm::mk_port::<task::task_notification>();
|
||||
task::spawn_notify(bind failer(), p.mk_chan());
|
||||
let f = failer;
|
||||
task::spawn_notify(f, p.mk_chan());
|
||||
let s = p.recv();
|
||||
log_err "received task status message";
|
||||
log_err s;
|
||||
|
Loading…
Reference in New Issue
Block a user