Skip to content

Commit

Permalink
Using move-mode for spawn thunks to avoid race conditions.
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Holk committed Aug 17, 2011
1 parent 1d7ca9c commit 94260fb
Show file tree
Hide file tree
Showing 16 changed files with 60 additions and 31 deletions.
9 changes: 5 additions & 4 deletions src/lib/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
5 changes: 4 additions & 1 deletion src/lib/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions src/test/bench/task-perf-spawnalot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand All @@ -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;
}
}
4 changes: 2 additions & 2 deletions src/test/bench/task-perf-word-count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down
3 changes: 2 additions & 1 deletion src/test/run-fail/linked-failure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
5 changes: 3 additions & 2 deletions src/test/run-pass/binops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion src/test/run-pass/issue-506.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
3 changes: 2 additions & 1 deletion src/test/run-pass/join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 7 additions & 2 deletions src/test/run-pass/task-comm-1.rs
Original file line number Diff line number Diff line change
@@ -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.";
}
12 changes: 8 additions & 4 deletions src/test/run-pass/task-comm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.";
}

Expand All @@ -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();
Expand All @@ -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); }
Expand Down
5 changes: 3 additions & 2 deletions src/test/run-pass/task-compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions src/test/run-pass/task-killjoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
3 changes: 2 additions & 1 deletion src/test/run-pass/yield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
3 changes: 2 additions & 1 deletion src/test/run-pass/yield1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/yield2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ use std;
fn main() {
let i: int = 0;
while i < 100 { i = i + 1; log_err i; std::task::yield(); }
}
}
12 changes: 8 additions & 4 deletions src/test/stdtest/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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]
Expand All @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 94260fb

Please sign in to comment.