// Copyright 2012-2013 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
 * Task management.
 *
 * An executing Rust program consists of a tree of tasks, each with their own
 * stack, and sole ownership of their allocated heap data. Tasks communicate
 * with each other using ports and channels.
 *
 * When a task fails, that failure will propagate to its parent (the task
 * that spawned it) and the parent will fail as well. The reverse is not
 * true: when a parent task fails its children will continue executing. When
 * the root (main) task fails, all tasks fail, and then so does the entire
 * process.
 *
 * Tasks may execute in parallel and are scheduled automatically by the
 * runtime.
 *
 * # Example
 *
 * ```
 * do spawn {
 *     log(error, "Hello, World!");
 * }
 * ```
 */

#[allow(missing_doc)];

use prelude::*;

use cell::Cell;
use comm::{stream, Chan, GenericChan, GenericPort, Port};
use result::Result;
use result;
use rt::in_green_task_context;
use rt::local::Local;
use unstable::finally::Finally;
use util;

#[cfg(test)] use cast;
#[cfg(test)] use comm::SharedChan;
#[cfg(test)] use comm;
#[cfg(test)] use ptr;
#[cfg(test)] use task;

pub mod spawn;

/**
 * Indicates the manner in which a task exited.
 *
 * A task that completes without failing is considered to exit successfully.
 * Supervised ancestors and linked siblings may yet fail after this task
 * succeeds. Also note that in such a case, it may be nondeterministic whether
 * linked failure or successful exit happen first.
 *
 * If you wish for this result's delivery to block until all linked and/or
 * children tasks complete, recommend using a result future.
 */
#[deriving(Eq)]
pub enum TaskResult {
    Success,
    Failure,
}

/// Scheduler modes
#[deriving(Eq)]
pub enum SchedMode {
    /// Run task on the default scheduler
    DefaultScheduler,
    /// All tasks run in the same OS thread
    SingleThreaded,
}

/**
 * Scheduler configuration options
 *
 * # Fields
 *
 * * sched_mode - The operating mode of the scheduler
 *
 */
pub struct SchedOpts {
    mode: SchedMode,
}

/**
 * Task configuration options
 *
 * # Fields
 *
 * * linked - Propagate failure bidirectionally between child and parent.
 *            True by default. If both this and 'supervised' are false, then
 *            either task's failure will not affect the other ("unlinked").
 *
 * * supervised - Propagate failure unidirectionally from parent to child,
 *                but not from child to parent. False by default.
 *
 * * watched - Make parent task collect exit status notifications from child
 *             before reporting its own exit status. (This delays the parent
 *             task's death and cleanup until after all transitively watched
 *             children also exit.) True by default.
 *
 * * indestructible - Configures the task to ignore kill signals received from
 *                    linked failure. This may cause process hangs during
 *                    failure if not used carefully, but causes task blocking
 *                    code paths (e.g. port recv() calls) to be faster by 2
 *                    atomic operations. False by default.
 *
 * * notify_chan - Enable lifecycle notifications on the given channel
 *
 * * name - A name for the task-to-be, for identification in failure messages.
 *
 * * sched - Specify the configuration of a new scheduler to create the task
 *           in
 *
 *     By default, every task is created in the same scheduler as its
 *     parent, where it is scheduled cooperatively with all other tasks
 *     in that scheduler. Some specialized applications may want more
 *     control over their scheduling, in which case they can be spawned
 *     into a new scheduler with the specific properties required.
 *
 *     This is of particular importance for libraries which want to call
 *     into foreign code that blocks. Without doing so in a different
 *     scheduler other tasks will be impeded or even blocked indefinitely.
 */
pub struct TaskOpts {
    linked: bool,
    supervised: bool,
    watched: bool,
    indestructible: bool,
    notify_chan: Option<Chan<TaskResult>>,
    name: Option<~str>,
    sched: SchedOpts,
    stack_size: Option<uint>
}

/**
 * The task builder type.
 *
 * Provides detailed control over the properties and behavior of new tasks.
 */
// NB: Builders are designed to be single-use because they do stateful
// things that get weird when reusing - e.g. if you create a result future
// it only applies to a single task, so then you have to maintain Some
// potentially tricky state to ensure that everything behaves correctly
// when you try to reuse the builder to spawn a new task. We'll just
// sidestep that whole issue by making builders uncopyable and making
// the run function move them in.

// FIXME (#3724): Replace the 'consumed' bit with move mode on self
pub struct TaskBuilder {
    opts: TaskOpts,
    gen_body: Option<~fn(v: ~fn()) -> ~fn()>,
    can_not_copy: Option<util::NonCopyable>,
    consumed: bool,
}

/**
 * Generate the base configuration for spawning a task, off of which more
 * configuration methods can be chained.
 * For example, task().unlinked().spawn is equivalent to spawn_unlinked.
 */
pub fn task() -> TaskBuilder {
    TaskBuilder {
        opts: default_task_opts(),
        gen_body: None,
        can_not_copy: None,
        consumed: false,
    }
}

impl TaskBuilder {
    fn consume(&mut self) -> TaskBuilder {
        if self.consumed {
            fail!("Cannot copy a task_builder"); // Fake move mode on self
        }
        self.consumed = true;
        let gen_body = self.gen_body.take();
        let notify_chan = self.opts.notify_chan.take();
        let name = self.opts.name.take();
        TaskBuilder {
            opts: TaskOpts {
                linked: self.opts.linked,
                supervised: self.opts.supervised,
                watched: self.opts.watched,
                indestructible: self.opts.indestructible,
                notify_chan: notify_chan,
                name: name,
                sched: self.opts.sched,
                stack_size: self.opts.stack_size
            },
            gen_body: gen_body,
            can_not_copy: None,
            consumed: false
        }
    }

    /// Decouple the child task's failure from the parent's. If either fails,
    /// the other will not be killed.
    pub fn unlinked(&mut self) {
        self.opts.linked = false;
        self.opts.watched = false;
    }

    /// Unidirectionally link the child task's failure with the parent's. The
    /// child's failure will not kill the parent, but the parent's will kill
    /// the child.
    pub fn supervised(&mut self) {
        self.opts.supervised = true;
        self.opts.linked = false;
        self.opts.watched = false;
    }

    /// Link the child task's and parent task's failures. If either fails, the
    /// other will be killed.
    pub fn linked(&mut self) {
        self.opts.linked = true;
        self.opts.supervised = false;
        self.opts.watched = true;
    }

    /// Cause the parent task to collect the child's exit status (and that of
    /// all transitively-watched grandchildren) before reporting its own.
    pub fn watched(&mut self) {
        self.opts.watched = true;
    }

    /// Allow the child task to outlive the parent task, at the possible cost
    /// of the parent reporting success even if the child task fails later.
    pub fn unwatched(&mut self) {
        self.opts.watched = false;
    }

    /// Cause the child task to ignore any kill signals received from linked
    /// failure. This optimizes context switching, at the possible expense of
    /// process hangs in the case of unexpected failure.
    pub fn indestructible(&mut self) {
        self.opts.indestructible = true;
    }

    /**
     * Get a future representing the exit status of the task.
     *
     * Taking the value of the future will block until the child task
     * terminates. The future-receiving callback specified will be called
     * *before* the task is spawned; as such, do not invoke .get() within the
     * closure; rather, store it in an outer variable/list for later use.
     *
     * Note that the future returning by this function is only useful for
     * obtaining the value of the next task to be spawning with the
     * builder. If additional tasks are spawned with the same builder
     * then a new result future must be obtained prior to spawning each
     * task.
     *
     * # Failure
     * Fails if a future_result was already set for this task.
     */
    pub fn future_result(&mut self, blk: &fn(v: Port<TaskResult>)) {
        // FIXME (#3725): Once linked failure and notification are
        // handled in the library, I can imagine implementing this by just
        // registering an arbitrary number of task::on_exit handlers and
        // sending out messages.

        if self.opts.notify_chan.is_some() {
            fail!("Can't set multiple future_results for one task!");
        }

        // Construct the future and give it to the caller.
        let (notify_pipe_po, notify_pipe_ch) = stream::<TaskResult>();

        blk(notify_pipe_po);

        // Reconfigure self to use a notify channel.
        self.opts.notify_chan = Some(notify_pipe_ch);
    }

    /// Name the task-to-be. Currently the name is used for identification
    /// only in failure messages.
    pub fn name(&mut self, name: ~str) {
        self.opts.name = Some(name);
    }

    /// Configure a custom scheduler mode for the task.
    pub fn sched_mode(&mut self, mode: SchedMode) {
        self.opts.sched.mode = mode;
    }

    /**
     * Add a wrapper to the body of the spawned task.
     *
     * Before the task is spawned it is passed through a 'body generator'
     * function that may perform local setup operations as well as wrap
     * the task body in remote setup operations. With this the behavior
     * of tasks can be extended in simple ways.
     *
     * This function augments the current body generator with a new body
     * generator by applying the task body which results from the
     * existing body generator to the new body generator.
     */
    pub fn add_wrapper(&mut self, wrapper: ~fn(v: ~fn()) -> ~fn()) {
        let prev_gen_body = self.gen_body.take();
        let prev_gen_body = match prev_gen_body {
            Some(gen) => gen,
            None => {
                let f: ~fn(~fn()) -> ~fn() = |body| body;
                f
            }
        };
        let prev_gen_body = Cell::new(prev_gen_body);
        let next_gen_body = {
            let f: ~fn(~fn()) -> ~fn() = |body| {
                let prev_gen_body = prev_gen_body.take();
                wrapper(prev_gen_body(body))
            };
            f
        };
        self.gen_body = Some(next_gen_body);
    }

    /**
     * Creates and executes a new child task
     *
     * Sets up a new task with its own call stack and schedules it to run
     * the provided unique closure. The task has the properties and behavior
     * specified by the task_builder.
     *
     * # Failure
     *
     * When spawning into a new scheduler, the number of threads requested
     * must be greater than zero.
     */
    pub fn spawn(&mut self, f: ~fn()) {
        let gen_body = self.gen_body.take();
        let notify_chan = self.opts.notify_chan.take();
        let name = self.opts.name.take();
        let x = self.consume();
        let opts = TaskOpts {
            linked: x.opts.linked,
            supervised: x.opts.supervised,
            watched: x.opts.watched,
            indestructible: x.opts.indestructible,
            notify_chan: notify_chan,
            name: name,
            sched: x.opts.sched,
            stack_size: x.opts.stack_size
        };
        let f = match gen_body {
            Some(gen) => {
                gen(f)
            }
            None => {
                f
            }
        };
        spawn::spawn_raw(opts, f);
    }

    /// Runs a task, while transferring ownership of one argument to the child.
    pub fn spawn_with<A:Send>(&mut self, arg: A, f: ~fn(v: A)) {
        let arg = Cell::new(arg);
        do self.spawn {
            f(arg.take());
        }
    }

    /**
     * Execute a function in another task and return either the return value
     * of the function or result::err.
     *
     * # Return value
     *
     * If the function executed successfully then try returns result::ok
     * containing the value returned by the function. If the function fails
     * then try returns result::err containing nil.
     *
     * # Failure
     * Fails if a future_result was already set for this task.
     */
    pub fn try<T:Send>(&mut self, f: ~fn() -> T) -> Result<T,()> {
        let (po, ch) = stream::<T>();
        let mut result = None;

        self.future_result(|r| { result = Some(r); });

        do self.spawn {
            ch.send(f());
        }

        match result.unwrap().recv() {
            Success => result::Ok(po.recv()),
            Failure => result::Err(())
        }
    }
}


/* Task construction */

pub fn default_task_opts() -> TaskOpts {
    /*!
     * The default task options
     *
     * By default all tasks are supervised by their parent, are spawned
     * into the same scheduler, and do not post lifecycle notifications.
     */

    TaskOpts {
        linked: true,
        supervised: false,
        watched: true,
        indestructible: false,
        notify_chan: None,
        name: None,
        sched: SchedOpts {
            mode: DefaultScheduler,
        },
        stack_size: None
    }
}

/* Spawn convenience functions */

/// Creates and executes a new child task
///
/// Sets up a new task with its own call stack and schedules it to run
/// the provided unique closure.
///
/// This function is equivalent to `task().spawn(f)`.
pub fn spawn(f: ~fn()) {
    let mut task = task();
    task.spawn(f)
}

/// Creates a child task unlinked from the current one. If either this
/// task or the child task fails, the other will not be killed.
pub fn spawn_unlinked(f: ~fn()) {
    let mut task = task();
    task.unlinked();
    task.spawn(f)
}

pub fn spawn_supervised(f: ~fn()) {
    /*!
     * Creates a child task supervised by the current one. If the child
     * task fails, the parent will not be killed, but if the parent fails,
     * the child will be killed.
     */

    let mut task = task();
    task.supervised();
    task.spawn(f)
}

/// Creates a child task that cannot be killed by linked failure. This causes
/// its context-switch path to be faster by 2 atomic swap operations.
/// (Note that this convenience wrapper still uses linked-failure, so the
/// child's children will still be killable by the parent. For the fastest
/// possible spawn mode, use task::task().unlinked().indestructible().spawn.)
pub fn spawn_indestructible(f: ~fn()) {
    let mut task = task();
    task.indestructible();
    task.spawn(f)
}

pub fn spawn_with<A:Send>(arg: A, f: ~fn(v: A)) {
    /*!
     * Runs a task, while transferring ownership of one argument to the
     * child.
     *
     * This is useful for transferring ownership of noncopyables to
     * another task.
     *
     * This function is equivalent to `task().spawn_with(arg, f)`.
     */

    let mut task = task();
    task.spawn_with(arg, f)
}

pub fn spawn_sched(mode: SchedMode, f: ~fn()) {
    /*!
     * Creates a new task on a new or existing scheduler

     * When there are no more tasks to execute the
     * scheduler terminates.
     *
     * # Failure
     *
     * In manual threads mode the number of threads requested must be
     * greater than zero.
     */

    let mut task = task();
    task.sched_mode(mode);
    task.spawn(f)
}

pub fn try<T:Send>(f: ~fn() -> T) -> Result<T,()> {
    /*!
     * Execute a function in another task and return either the return value
     * of the function or result::err.
     *
     * This is equivalent to task().supervised().try.
     */

    let mut task = task();
    task.supervised();
    task.try(f)
}


/* Lifecycle functions */

/// Read the name of the current task.
pub fn with_task_name<U>(blk: &fn(Option<&str>) -> U) -> U {
    use rt::task::Task;

    if in_green_task_context() {
        do Local::borrow |task: &mut Task| {
            match task.name {
                Some(ref name) => blk(Some(name.as_slice())),
                None => blk(None)
            }
        }
    } else {
        fail!("no task name exists in non-green task context")
    }
}

pub fn deschedule() {
    //! Yield control to the task scheduler

    use rt::local::Local;
    use rt::sched::Scheduler;

    // FIXME #6842: What does yield really mean in newsched?
    // FIXME(#7544): Optimize this, since we know we won't block.
    let sched: ~Scheduler = Local::take();
    do sched.deschedule_running_task_and_then |sched, task| {
        sched.enqueue_blocked_task(task);
    }
}

pub fn failing() -> bool {
    //! True if the running task has failed

    use rt::task::Task;

    do Local::borrow |local: &mut Task| {
        local.unwinder.unwinding
    }
}

/**
 * Temporarily make the task unkillable
 *
 * # Example
 *
 * ```
 * do task::unkillable {
 *     // detach / deschedule / destroy must all be called together
 *     rustrt::rust_port_detach(po);
 *     // This must not result in the current task being killed
 *     task::deschedule();
 *     rustrt::rust_port_destroy(po);
 * }
 * ```
 */
pub fn unkillable<U>(f: &fn() -> U) -> U {
    use rt::task::Task;

    unsafe {
        if in_green_task_context() {
            // The inhibits/allows might fail and need to borrow the task.
            let t: *mut Task = Local::unsafe_borrow();
            do (|| {
                (*t).death.inhibit_kill((*t).unwinder.unwinding);
                f()
            }).finally {
                (*t).death.allow_kill((*t).unwinder.unwinding);
            }
        } else {
            // FIXME(#3095): This should be an rtabort as soon as the scheduler
            // no longer uses a workqueue implemented with an Exclusive.
            f()
        }
    }
}

/**
 * Makes killable a task marked as unkillable. This
 * is meant to be used only nested in unkillable.
 *
 * # Example
 *
 * ```
 * do task::unkillable {
 *     do task::rekillable {
 *          // Task is killable
 *     }
 *    // Task is unkillable again
 * }
 */
pub fn rekillable<U>(f: &fn() -> U) -> U {
    use rt::task::Task;

    unsafe {
        if in_green_task_context() {
            let t: *mut Task = Local::unsafe_borrow();
            do (|| {
                (*t).death.allow_kill((*t).unwinder.unwinding);
                f()
            }).finally {
                (*t).death.inhibit_kill((*t).unwinder.unwinding);
            }
        } else {
            // FIXME(#3095): As in unkillable().
            f()
        }
    }
}

#[ignore(reason = "linked failure")]
#[test]
fn test_kill_unkillable_task() {
    use rt::test::*;

    // Attempt to test that when a kill signal is received at the start of an
    // unkillable section, 'unkillable' unwinds correctly. This is actually
    // quite a difficult race to expose, as the kill has to happen on a second
    // CPU, *after* the spawner is already switched-back-to (and passes the
    // killed check at the start of its timeslice). As far as I know, it's not
    // possible to make this race deterministic, or even more likely to happen.
    do run_in_newsched_task {
        do task::try {
            do task::spawn {
                fail!();
            }
            do task::unkillable { }
        };
    }
}

#[test]
#[ignore(cfg(windows))]
fn test_kill_rekillable_task() {
    use rt::test::*;

    // Tests that when a kill signal is received, 'rekillable' and
    // 'unkillable' unwind correctly in conjunction with each other.
    do run_in_newsched_task {
        do task::try {
            do task::unkillable {
                do task::rekillable {
                    do task::spawn {
                        fail!();
                    }
                }
            }
        };
    }
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_rekillable_not_nested() {
    do rekillable {
        // This should fail before
        // receiving anything since
        // this block should be nested
        // into a unkillable block.
        deschedule();
    }
}


#[test]
#[ignore(cfg(windows))]
fn test_rekillable_nested_failure() {

    let result = do task::try {
        do unkillable {
            do rekillable {
                let (port,chan) = comm::stream();
                do task::spawn { chan.send(()); fail!(); }
                port.recv(); // wait for child to exist
                port.recv(); // block forever, expect to get killed.
            }
        }
    };
    assert!(result.is_err());
}


#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_cant_dup_task_builder() {
    let mut builder = task();
    builder.unlinked();
    do builder.spawn {}
    // FIXME(#3724): For now, this is a -runtime- failure, because we haven't
    // got move mode on self. When 3724 is fixed, this test should fail to
    // compile instead, and should go in tests/compile-fail.
    do builder.spawn {} // b should have been consumed by the previous call
}

// The following 8 tests test the following 2^3 combinations:
// {un,}linked {un,}supervised failure propagation {up,down}wards.

// !!! These tests are dangerous. If Something is buggy, they will hang, !!!
// !!! instead of exiting cleanly. This might wedge the buildbots.       !!!

#[cfg(test)]
fn block_forever() { let (po, _ch) = stream::<()>(); po.recv(); }

#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let (po, ch) = stream();
        let ch = SharedChan::new(ch);
        do spawn_unlinked {
            let ch = ch.clone();
            do spawn_unlinked {
                // Give middle task a chance to fail-but-not-kill-us.
                do 16.times { task::deschedule(); }
                ch.send(()); // If killed first, grandparent hangs.
            }
            fail!(); // Shouldn't kill either (grand)parent or (grand)child.
        }
        po.recv();
    }
}
#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        do spawn_unlinked { fail!(); }
    }
}
#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        do spawn_supervised { fail!(); }
        // Give child a chance to fail-but-not-kill-us.
        do 16.times { task::deschedule(); }
    }
}
#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_unlinked_sup_fail_down() {
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            do spawn_supervised { block_forever(); }
            fail!(); // Shouldn't leave a child hanging around.
        };
        assert!(result.is_err());
    }
}

#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // Unidirectional "parenting" shouldn't override bidirectional linked.
            // We have to cheat with opts - the interface doesn't support them because
            // they don't make sense (redundant with task().supervised()).
            let mut b0 = task();
            b0.opts.linked = true;
            b0.opts.supervised = true;

            do b0.spawn {
                fail!();
            }
            block_forever(); // We should get punted awake
        };
        assert!(result.is_err());
    }
}
#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // We have to cheat with opts - the interface doesn't support them because
            // they don't make sense (redundant with task().supervised()).
            let mut b0 = task();
            b0.opts.linked = true;
            b0.opts.supervised = true;
            do b0.spawn { block_forever(); }
            fail!(); // *both* mechanisms would be wrong if this didn't kill the child
        };
        assert!(result.is_err());
    }
}
#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // Default options are to spawn linked & unsupervised.
            do spawn { fail!(); }
            block_forever(); // We should get punted awake
        };
        assert!(result.is_err());
    }
}
#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // Default options are to spawn linked & unsupervised.
            do spawn { block_forever(); }
            fail!();
        };
        assert!(result.is_err());
    }
}
#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // Make sure the above test is the same as this one.
            let mut builder = task();
            builder.linked();
            do builder.spawn { block_forever(); }
            fail!();
        };
        assert!(result.is_err());
    }
}

// A couple bonus linked failure tests - testing for failure propagation even
// when the middle task exits successfully early before kill signals are sent.

#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_failure_propagate_grandchild() {
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // Middle task exits; does grandparent's failure propagate across the gap?
            do spawn_supervised {
                do spawn_supervised { block_forever(); }
            }
            do 16.times { task::deschedule(); }
            fail!();
        };
        assert!(result.is_err());
    }
}

#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_failure_propagate_secondborn() {
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // First-born child exits; does parent's failure propagate to sibling?
            do spawn_supervised {
                do spawn { block_forever(); } // linked
            }
            do 16.times { task::deschedule(); }
            fail!();
        };
        assert!(result.is_err());
    }
}

#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_failure_propagate_nephew_or_niece() {
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // Our sibling exits; does our failure propagate to sibling's child?
            do spawn { // linked
                do spawn_supervised { block_forever(); }
            }
            do 16.times { task::deschedule(); }
            fail!();
        };
        assert!(result.is_err());
    }
}

#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_linked_sup_propagate_sibling() {
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result: Result<(),()> = do try {
            // Middle sibling exits - does eldest's failure propagate to youngest?
            do spawn { // linked
                do spawn { block_forever(); } // linked
            }
            do 16.times { task::deschedule(); }
            fail!();
        };
        assert!(result.is_err());
    }
}

#[test]
fn test_unnamed_task() {
    use rt::test::run_in_newsched_task;

    do run_in_newsched_task {
        do spawn {
            do with_task_name |name| {
                assert!(name.is_none());
            }
        }
    }
}

#[test]
fn test_named_task() {
    use rt::test::run_in_newsched_task;

    do run_in_newsched_task {
        let mut t = task();
        t.name(~"ada lovelace");
        do t.spawn {
            do with_task_name |name| {
                assert!(name.unwrap() == "ada lovelace");
            }
        }
    }
}

#[test]
fn test_run_basic() {
    let (po, ch) = stream::<()>();
    let mut builder = task();
    do builder.spawn {
        ch.send(());
    }
    po.recv();
}

#[cfg(test)]
struct Wrapper {
    f: Option<Chan<()>>
}

#[test]
fn test_add_wrapper() {
    let (po, ch) = stream::<()>();
    let mut b0 = task();
    let ch = Cell::new(ch);
    do b0.add_wrapper |body| {
        let ch = Cell::new(ch.take());
        let result: ~fn() = || {
            let ch = ch.take();
            body();
            ch.send(());
        };
        result
    };
    do b0.spawn { }
    po.recv();
}

#[test]
fn test_future_result() {
    let mut result = None;
    let mut builder = task();
    builder.future_result(|r| result = Some(r));
    do builder.spawn {}
    assert_eq!(result.unwrap().recv(), Success);

    result = None;
    let mut builder = task();
    builder.future_result(|r| result = Some(r));
    builder.unlinked();
    do builder.spawn {
        fail!();
    }
    assert_eq!(result.unwrap().recv(), Failure);
}

#[test] #[should_fail]
fn test_back_to_the_future_result() {
    let mut builder = task();
    builder.future_result(util::ignore);
    builder.future_result(util::ignore);
}

#[test]
fn test_try_success() {
    match do try {
        ~"Success!"
    } {
        result::Ok(~"Success!") => (),
        _ => fail!()
    }
}

#[test]
fn test_try_fail() {
    match do try {
        fail!()
    } {
        result::Err(()) => (),
        result::Ok(()) => fail!()
    }
}

#[cfg(test)]
fn get_sched_id() -> int {
    do Local::borrow |sched: &mut ::rt::sched::Scheduler| {
        sched.sched_id() as int
    }
}

#[test]
fn test_spawn_sched() {
    let (po, ch) = stream::<()>();
    let ch = SharedChan::new(ch);

    fn f(i: int, ch: SharedChan<()>) {
        let parent_sched_id = get_sched_id();

        do spawn_sched(SingleThreaded) {
            let child_sched_id = get_sched_id();
            assert!(parent_sched_id != child_sched_id);

            if (i == 0) {
                ch.send(());
            } else {
                f(i - 1, ch.clone());
            }
        };

    }
    f(10, ch);
    po.recv();
}

#[test]
fn test_spawn_sched_childs_on_default_sched() {
    let (po, ch) = stream();

    // Assuming tests run on the default scheduler
    let default_id = get_sched_id();

    let ch = Cell::new(ch);
    do spawn_sched(SingleThreaded) {
        let parent_sched_id = get_sched_id();
        let ch = Cell::new(ch.take());
        do spawn {
            let ch = ch.take();
            let child_sched_id = get_sched_id();
            assert!(parent_sched_id != child_sched_id);
            assert_eq!(child_sched_id, default_id);
            ch.send(());
        };
    };

    po.recv();
}

#[cfg(test)]
mod testrt {
    use libc;

    externfn!(fn rust_dbg_lock_create() -> *libc::c_void)
    externfn!(fn rust_dbg_lock_destroy(lock: *libc::c_void))
    externfn!(fn rust_dbg_lock_lock(lock: *libc::c_void))
    externfn!(fn rust_dbg_lock_unlock(lock: *libc::c_void))
    externfn!(fn rust_dbg_lock_wait(lock: *libc::c_void))
    externfn!(fn rust_dbg_lock_signal(lock: *libc::c_void))
}

#[test]
fn test_spawn_sched_blocking() {
    unsafe {

        // Testing that a task in one scheduler can block in foreign code
        // without affecting other schedulers
        do 20u.times {
            let (start_po, start_ch) = stream();
            let (fin_po, fin_ch) = stream();

            let lock = testrt::rust_dbg_lock_create();

            do spawn_sched(SingleThreaded) {
                testrt::rust_dbg_lock_lock(lock);

                start_ch.send(());

                // Block the scheduler thread
                testrt::rust_dbg_lock_wait(lock);
                testrt::rust_dbg_lock_unlock(lock);

                fin_ch.send(());
            };

            // Wait until the other task has its lock
            start_po.recv();

            fn pingpong(po: &Port<int>, ch: &Chan<int>) {
                let mut val = 20;
                while val > 0 {
                    val = po.recv();
                    ch.send(val - 1);
                }
            }

            let (setup_po, setup_ch) = stream();
            let (parent_po, parent_ch) = stream();
            do spawn {
                let (child_po, child_ch) = stream();
                setup_ch.send(child_ch);
                pingpong(&child_po, &parent_ch);
            };

            let child_ch = setup_po.recv();
            child_ch.send(20);
            pingpong(&parent_po, &child_ch);
            testrt::rust_dbg_lock_lock(lock);
            testrt::rust_dbg_lock_signal(lock);
            testrt::rust_dbg_lock_unlock(lock);
            fin_po.recv();
            testrt::rust_dbg_lock_destroy(lock);
        }
    }
}

#[cfg(test)]
fn avoid_copying_the_body(spawnfn: &fn(v: ~fn())) {
    let (p, ch) = stream::<uint>();

    let x = ~1;
    let x_in_parent = ptr::to_unsafe_ptr(&*x) as uint;

    do spawnfn || {
        let x_in_child = ptr::to_unsafe_ptr(&*x) as uint;
        ch.send(x_in_child);
    }

    let x_in_child = p.recv();
    assert_eq!(x_in_parent, x_in_child);
}

#[test]
fn test_avoid_copying_the_body_spawn() {
    avoid_copying_the_body(spawn);
}

#[test]
fn test_avoid_copying_the_body_task_spawn() {
    do avoid_copying_the_body |f| {
        let mut builder = task();
        do builder.spawn || {
            f();
        }
    }
}

#[test]
fn test_avoid_copying_the_body_try() {
    do avoid_copying_the_body |f| {
        do try || {
            f()
        };
    }
}

#[test]
fn test_avoid_copying_the_body_unlinked() {
    do avoid_copying_the_body |f| {
        do spawn_unlinked || {
            f();
        }
    }
}

#[ignore(reason = "linked failure")]
#[test]
#[should_fail]
fn test_unkillable() {
    let (po, ch) = stream();

    // We want to do this after failing
    do spawn_unlinked {
        do 10.times { deschedule() }
        ch.send(());
    }

    do spawn {
        deschedule();
        // We want to fail after the unkillable task
        // blocks on recv
        fail!();
    }

    unsafe {
        do unkillable {
            let p = ~0;
            let pp: *uint = cast::transmute(p);

            // If we are killed here then the box will leak
            po.recv();

            let _p: ~int = cast::transmute(pp);
        }
    }

    // Now we can be killed
    po.recv();
}

#[ignore(reason = "linked failure")]
#[test]
#[should_fail]
fn test_unkillable_nested() {
    let (po, ch) = comm::stream();

    // We want to do this after failing
    do spawn_unlinked || {
        do 10.times { deschedule() }
        ch.send(());
    }

    do spawn {
        deschedule();
        // We want to fail after the unkillable task
        // blocks on recv
        fail!();
    }

    unsafe {
        do unkillable {
            do unkillable {} // Here's the difference from the previous test.
            let p = ~0;
            let pp: *uint = cast::transmute(p);

            // If we are killed here then the box will leak
            po.recv();

            let _p: ~int = cast::transmute(pp);
        }
    }

    // Now we can be killed
    po.recv();
}

#[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)
    // (well, it would if the constant were 8000+ - I lowered it to be more
    // valgrind-friendly. try this at home, instead..!)
    static generations: uint = 16;
    fn child_no(x: uint) -> ~fn() {
        return || {
            if x < generations {
                let mut t = task();
                t.unwatched();
                t.spawn(child_no(x+1));
            }
        }
    }
    let mut t = task();
    t.unwatched();
    t.spawn(child_no(0));
}

#[test]
fn test_simple_newsched_spawn() {
    use rt::test::run_in_newsched_task;

    do run_in_newsched_task {
        spawn(||())
    }
}

#[ignore(reason = "linked failure")]
#[test]
fn test_spawn_watched() {
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result = do try {
            let mut t = task();
            t.unlinked();
            t.watched();
            do t.spawn {
                let mut t = task();
                t.unlinked();
                t.watched();
                do t.spawn {
                    task::deschedule();
                    fail!();
                }
            }
        };
        assert!(result.is_err());
    }
}

#[ignore(reason = "linked failure")]
#[test]
fn test_indestructible() {
    use rt::test::run_in_newsched_task;
    do run_in_newsched_task {
        let result = do try {
            let mut t = task();
            t.watched();
            t.supervised();
            t.indestructible();
            do t.spawn {
                let (p1, _c1) = stream::<()>();
                let (p2, c2) = stream::<()>();
                let (p3, c3) = stream::<()>();
                let mut t = task();
                t.unwatched();
                do t.spawn {
                    do (|| {
                        p1.recv(); // would deadlock if not killed
                    }).finally {
                        c2.send(());
                    };
                }
                let mut t = task();
                t.unwatched();
                do t.spawn {
                    p3.recv();
                    task::deschedule();
                    fail!();
                }
                c3.send(());
                p2.recv();
            }
        };
        assert!(result.is_ok());
    }
}
