From 94260fb91d3e8a11f39eafc1c21bc974713db166 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 17 Aug 2011 11:44:35 -0700 Subject: [PATCH] Using move-mode for spawn thunks to avoid race conditions. --- src/lib/task.rs | 9 +++++---- src/lib/test.rs | 5 ++++- src/test/bench/task-perf-spawnalot.rs | 5 +++-- src/test/bench/task-perf-word-count.rs | 4 ++-- src/test/run-fail/linked-failure.rs | 3 ++- src/test/run-pass/binops.rs | 5 +++-- src/test/run-pass/issue-506.rs | 5 ++++- src/test/run-pass/join.rs | 3 ++- src/test/run-pass/task-comm-1.rs | 9 +++++++-- src/test/run-pass/task-comm.rs | 12 ++++++++---- src/test/run-pass/task-compare.rs | 5 +++-- src/test/run-pass/task-killjoin.rs | 6 ++++-- src/test/run-pass/yield.rs | 3 ++- src/test/run-pass/yield1.rs | 3 ++- src/test/run-pass/yield2.rs | 2 +- src/test/stdtest/task.rs | 12 ++++++++---- 16 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/lib/task.rs b/src/lib/task.rs index 434092b524a..d010afc5217 100644 --- a/src/lib/task.rs +++ b/src/lib/task.rs @@ -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) +fn spawn_notify(thunk : -fn() -> (), notify : _chan) -> task { spawn_inner(thunk, some(notify)) } // FIXME: make this a fn~ once those are supported. -fn spawn_inner(thunk : fn() -> (), notify : option<_chan>) +fn spawn_inner(thunk : -fn() -> (), + notify : option<_chan>) -> task_id { let id = rustrt::new_task(); diff --git a/src/lib/test.rs b/src/lib/test.rs index 5b6d6b34c97..2b4d1f2714a 100644 --- a/src/lib/test.rs +++ b/src/lib/test.rs @@ -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 diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs index 50182155ad9..48e1b4d8087 100644 --- a/src/test/bench/task-perf-spawnalot.rs +++ b/src/test/bench/task-perf-spawnalot.rs @@ -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; } } diff --git a/src/test/bench/task-perf-word-count.rs b/src/test/bench/task-perf-word-count.rs index 914446e1300..54bfae13c23 100644 --- a/src/test/bench/task-perf-word-count.rs +++ b/src/test/bench/task-perf-word-count.rs @@ -77,7 +77,7 @@ mod map_reduce { fn start_mappers(ctrl: _chan, 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); } diff --git a/src/test/run-fail/linked-failure.rs b/src/test/run-fail/linked-failure.rs index 9d076b0203c..e3122b283b1 100644 --- a/src/test/run-fail/linked-failure.rs +++ b/src/test/run-fail/linked-failure.rs @@ -11,6 +11,7 @@ fn child() { assert (1 == 2); } fn main() { let p = mk_port::(); - task::_spawn(bind child()); + let f = child; + task::_spawn(f); let x = p.recv(); } diff --git a/src/test/run-pass/binops.rs b/src/test/run-pass/binops.rs index 511dcda6b26..8fab2a68539 100644 --- a/src/test/run-pass/binops.rs +++ b/src/test/run-pass/binops.rs @@ -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; diff --git a/src/test/run-pass/issue-506.rs b/src/test/run-pass/issue-506.rs index cb3e972d679..3487c1a7f37 100644 --- a/src/test/run-pass/issue-506.rs +++ b/src/test/run-pass/issue-506.rs @@ -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); +} diff --git a/src/test/run-pass/join.rs b/src/test/run-pass/join.rs index 1856d80cafb..5545aadb1fb 100644 --- a/src/test/run-pass/join.rs +++ b/src/test/run-pass/join.rs @@ -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); diff --git a/src/test/run-pass/task-comm-1.rs b/src/test/run-pass/task-comm-1.rs index f5a3e268a85..2b19e66d673 100644 --- a/src/test/run-pass/task-comm-1.rs +++ b/src/test/run-pass/task-comm-1.rs @@ -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."; +} diff --git a/src/test/run-pass/task-comm.rs b/src/test/run-pass/task-comm.rs index e906c47dfc4..c468d1c89d6 100644 --- a/src/test/run-pass/task-comm.rs +++ b/src/test/run-pass/task-comm.rs @@ -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) { 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); } diff --git a/src/test/run-pass/task-compare.rs b/src/test/run-pass/task-compare.rs index 39eff3eb78e..3100d6d3d3b 100644 --- a/src/test/run-pass/task-compare.rs +++ b/src/test/run-pass/task-compare.rs @@ -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); diff --git a/src/test/run-pass/task-killjoin.rs b/src/test/run-pass/task-killjoin.rs index 48b27aca5cb..cfed8c136ab 100644 --- a/src/test/run-pass/task-killjoin.rs +++ b/src/test/run-pass/task-killjoin.rs @@ -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); } diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs index 500ba42d8f6..8de4b6c411f 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/run-pass/yield.rs @@ -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"; diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs index bbaafd9bf1f..e53591dbe1a 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/run-pass/yield1.rs @@ -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); } diff --git a/src/test/run-pass/yield2.rs b/src/test/run-pass/yield2.rs index ae1858c88bb..819f6d79cac 100644 --- a/src/test/run-pass/yield2.rs +++ b/src/test/run-pass/yield2.rs @@ -4,4 +4,4 @@ use std; fn main() { let i: int = 0; while i < 100 { i = i + 1; log_err i; std::task::yield(); } -} \ No newline at end of file +} diff --git a/src/test/stdtest/task.rs b/src/test/stdtest/task.rs index c46944bdeb2..6e6c2e0673f 100644 --- a/src/test/stdtest/task.rs +++ b/src/test/stdtest/task.rs @@ -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::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::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;