diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-12-15 00:42:21 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-12-24 19:59:54 -0800 |
| commit | 51c03c1f35f6b076928a1e5b94ec81e6d00c3ac2 (patch) | |
| tree | 5503ef16e6be59f8a0c8948fe347d48be9267a47 /src/libstd/rt/task.rs | |
| parent | 282f3d99a5ad85acbc58c03b5dfcdabf649c0c85 (diff) | |
| download | rust-51c03c1f35f6b076928a1e5b94ec81e6d00c3ac2.tar.gz rust-51c03c1f35f6b076928a1e5b94ec81e6d00c3ac2.zip | |
green: Properly wait for main before shutdown
There was a race in the code previously where schedulers would *immediately* shut down after spawning the main task (because the global task count would still be 0). This fixes the logic by blocking the sched pool task in receving on a port instead of spawning a task into the pool to receive on a port. The modifications necessary were to have a "simple task" running by the time the code is executing, but this is a simple enough thing to implement and I forsee this being necessary to have implemented in the future anyway.
Diffstat (limited to 'src/libstd/rt/task.rs')
| -rw-r--r-- | src/libstd/rt/task.rs | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index c0e1086483d..765f0b427cd 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -292,6 +292,21 @@ impl Task { pub fn local_io<'a>(&'a mut self) -> Option<LocalIo<'a>> { self.imp.get_mut_ref().local_io() } + + /// The main function of all rust executables will by default use this + /// function. This function will *block* the OS thread (hence the `unsafe`) + /// waiting for all known tasks to complete. Once this function has + /// returned, it is guaranteed that no more user-defined code is still + /// running. + pub unsafe fn wait_for_other_tasks(&mut self) { + TASK_COUNT.fetch_sub(1, SeqCst); // don't count ourselves + TASK_LOCK.lock(); + while TASK_COUNT.load(SeqCst) > 0 { + TASK_LOCK.wait(); + } + TASK_LOCK.unlock(); + TASK_COUNT.fetch_add(1, SeqCst); // add ourselves back in + } } impl Drop for Task { @@ -396,18 +411,6 @@ impl Drop for Death { } } -/// The main function of all rust executables will by default use this function. -/// This function will *block* the OS thread (hence the `unsafe`) waiting for -/// all known tasks to complete. Once this function has returned, it is -/// guaranteed that no more user-defined code is still running. -pub unsafe fn wait_for_completion() { - TASK_LOCK.lock(); - while TASK_COUNT.load(SeqCst) > 0 { - TASK_LOCK.wait(); - } - TASK_LOCK.unlock(); -} - #[cfg(test)] mod test { use super::*; |
