about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorBen Blum <bblum@andrew.cmu.edu>2012-07-17 20:40:40 -0400
committerBen Blum <bblum@andrew.cmu.edu>2012-07-17 20:45:07 -0400
commit4cf6b4d3b4ea5cd231ab96d82f5f8cd794e0b2c3 (patch)
tree3f9ca49a7c78422148869b50df72f999c706cbe2 /src/libcore
parentd930d717e5f4557e47c9fd5bdca62a92f5cc8c38 (diff)
downloadrust-4cf6b4d3b4ea5cd231ab96d82f5f8cd794e0b2c3.tar.gz
rust-4cf6b4d3b4ea5cd231ab96d82f5f8cd794e0b2c3.zip
Tasks should not hold a ref to their parent (Close #1789)
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/sys.rs1
-rw-r--r--src/libcore/task.rs26
2 files changed, 17 insertions, 10 deletions
diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs
index 0e5a39e859e..7a23f0c3e0b 100644
--- a/src/libcore/sys.rs
+++ b/src/libcore/sys.rs
@@ -19,7 +19,6 @@ type rust_cond_lock = *libc::c_void;
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    fn unsupervise();
     pure fn shape_log_str(t: *sys::type_desc, data: *()) -> ~str;
 
     fn rust_create_cond_lock() -> rust_cond_lock;
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");