diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-17 20:40:40 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-17 20:45:07 -0400 |
| commit | 4cf6b4d3b4ea5cd231ab96d82f5f8cd794e0b2c3 (patch) | |
| tree | 3f9ca49a7c78422148869b50df72f999c706cbe2 /src/libcore/task.rs | |
| parent | d930d717e5f4557e47c9fd5bdca62a92f5cc8c38 (diff) | |
| download | rust-4cf6b4d3b4ea5cd231ab96d82f5f8cd794e0b2c3.tar.gz rust-4cf6b4d3b4ea5cd231ab96d82f5f8cd794e0b2c3.zip | |
Tasks should not hold a ref to their parent (Close #1789)
Diffstat (limited to 'src/libcore/task.rs')
| -rw-r--r-- | src/libcore/task.rs | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/src/libcore/task.rs b/src/libcore/task.rs index 0efc15cda2a..7f798dcf047 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -731,8 +731,7 @@ fn spawn_raw(opts: task_opts, +f: fn~()) { // Getting killed after here would leak the task. let child_wrapper = - make_child_wrapper(new_task, child_tg, - opts.supervise, is_main, f); + make_child_wrapper(new_task, child_tg, is_main, f); let fptr = ptr::addr_of(child_wrapper); let closure: *rust_closure = unsafe::reinterpret_cast(fptr); @@ -750,8 +749,7 @@ fn spawn_raw(opts: task_opts, +f: fn~()) { } fn make_child_wrapper(child_task: *rust_task, -child_tg: taskgroup_arc, - supervise: bool, is_main: bool, - -f: fn~()) -> fn~() { + is_main: bool, -f: fn~()) -> fn~() { let child_tg_ptr = ~mut some(child_tg); fn~() { // Agh. Get move-mode items into the closure. FIXME (#2829) @@ -759,10 +757,6 @@ fn spawn_raw(opts: task_opts, +f: fn~()) { *child_tg_ptr <-> child_tg_opt; let child_tg = option::unwrap(child_tg_opt); // Child task runs this code. - if !supervise { - // FIXME (#1868, #1789) take this out later - rustrt::unsupervise(); - } // Set up membership in taskgroup. If this returns none, the // parent was already failing, so don't bother doing anything. alt enlist_in_taskgroup(child_tg, child_task) { @@ -1018,7 +1012,6 @@ extern mod rustrt { fn start_task(task: *rust_task, closure: *rust_closure); fn rust_task_is_unwinding(task: *rust_task) -> bool; - fn unsupervise(); fn rust_osmain_sched_id() -> sched_id; fn rust_task_inhibit_kill(); fn rust_task_allow_kill(); @@ -1465,6 +1458,21 @@ fn test_unkillable_nested() { } #[test] +fn test_child_doesnt_ref_parent() { + // If the child refcounts the parent task, this will stack overflow when + // climbing the task tree to dereference each ancestor. (See #1789) + const generations: uint = 8192; + fn child_no(x: uint) -> fn~() { + ret || { + if x < generations { + task::spawn(child_no(x+1)); + } + } + } + task::spawn(child_no(0)); +} + +#[test] fn test_tls_multitask() unsafe { fn my_key(+_x: @~str) { } local_data_set(my_key, @~"parent data"); |
