diff --git a/src/libnative/task.rs b/src/libnative/task.rs index 661358a64e9..5a1ef5c836e 100644 --- a/src/libnative/task.rs +++ b/src/libnative/task.rs @@ -72,6 +72,11 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) { let task = task; let ops = ops(); + // Note that this increment must happen *before* the spawn in order to + // guarantee that if this task exits it will always end up waiting for the + // spawned task to exit. + bookeeping::increment(); + // Spawning a new OS thread guarantees that __morestack will never get // triggered, but we must manually set up the actual stack bounds once this // function starts executing. This raises the lower limit by a bit because @@ -88,7 +93,6 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) { let mut ops = ops; ops.stack_bounds = Some((my_stack - stack + 1024, my_stack)); - bookeeping::increment(); let mut f = Some(f); let mut task = task; task.put_runtime(ops as ~rt::Runtime); diff --git a/src/test/run-pass/native-always-waits.rs b/src/test/run-pass/native-always-waits.rs new file mode 100644 index 00000000000..c015ee30639 --- /dev/null +++ b/src/test/run-pass/native-always-waits.rs @@ -0,0 +1,28 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast + +extern mod native; + +static mut set: bool = false; + +#[start] +fn start(argc: int, argv: **u8) -> int { + // make sure that native::start always waits for all children to finish + do native::start(argc, argv) { + do spawn { + unsafe { set = true; } + } + }; + + // if we didn't set the global, then return a nonzero code + if unsafe {set} {0} else {1} +}