use super::stack::{StackPool, StackSegment};
use super::rtio::{EventLoop, EventLoopObject};
use super::context::Context;
+use super::local_services::LocalServices;
use cell::Cell;
#[cfg(test)] use super::uvio::UvEventLoop;
/// Always valid when a task is executing, otherwise not
priv saved_context: Context,
/// The currently executing task
- priv current_task: Option<~Task>,
+ current_task: Option<~Task>,
/// An action performed after a context switch on behalf of the
/// code running before the context switch
priv cleanup_job: Option<CleanupJob>
}
}
- // Control never reaches here
+ abort!("control reached end of task");
}
fn schedule_new_task(~self, task: ~Task) {
/// These are always valid when the task is not running, unless
/// the task is dead
priv saved_context: Context,
+ /// The heap, GC, unwinding, local storage, logging
+ local_services: LocalServices
}
pub impl Task {
fn new(stack_pool: &mut StackPool, start: ~fn()) -> Task {
+ Task::with_local(stack_pool, LocalServices::new(), start)
+ }
+
+ fn with_local(stack_pool: &mut StackPool,
+ local_services: LocalServices,
+ start: ~fn()) -> Task {
let start = Task::build_start_wrapper(start);
let mut stack = stack_pool.take_segment(TASK_MIN_STACK_SIZE);
// NB: Context holds a pointer to that ~fn
return Task {
current_stack_segment: stack,
saved_context: initial_context,
+ local_services: local_services
};
}
unsafe {
let sched = local_sched::unsafe_borrow();
sched.run_cleanup_job();
- }
- start();
+ let sched = local_sched::unsafe_borrow();
+ let task = sched.current_task.get_mut_ref();
+ // FIXME #6141: shouldn't neet to put `start()` in another closure
+ task.local_services.run(||start());
+ }
let sched = local_sched::take();
sched.terminate_current_task();