diff options
| author | bors <bors@rust-lang.org> | 2013-04-19 15:57:50 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-04-19 15:57:50 -0700 |
| commit | 6510fd92544467a03df93b5124644976aa79f964 (patch) | |
| tree | 58b8f87b6432f171e4dd7d0b82cc9adbb4938b83 /src/libcore/task | |
| parent | bffe23b0cfee2e6957a81a98f8c8a885522e3444 (diff) | |
| parent | 7270fadfccb8f7b767bf45bda106a55b6a874c03 (diff) | |
| download | rust-6510fd92544467a03df93b5124644976aa79f964.tar.gz rust-6510fd92544467a03df93b5124644976aa79f964.zip | |
auto merge of #5960 : brson/rust/io, r=pcwalton
r? This pull request is a grab bag of work on the new scheduler. The most important commit here is where I [outline](https://github.com/brson/rust/blob/io/src/libcore/rt/io/mod.rs) a fairly complete I/O API, based on `Reader` and `Writer` types, as in the current `core::io` module. I've organized this version into a number of modules with declarations for Files, TCP, UDP, Unix sockets, blocking/non-blocking implementations, memory buffers, compression adapters. I'm trying to get this into shape to present on the mailing list. This branch also wires up `spawn` to the new scheduler, and simplifies the core scheduler operations.
Diffstat (limited to 'src/libcore/task')
| -rw-r--r-- | src/libcore/task/mod.rs | 48 | ||||
| -rw-r--r-- | src/libcore/task/spawn.rs | 28 |
2 files changed, 69 insertions, 7 deletions
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 55546514e4f..a6c03638713 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -175,7 +175,7 @@ pub struct TaskOpts { // FIXME (#3724): Replace the 'consumed' bit with move mode on self pub struct TaskBuilder { opts: TaskOpts, - gen_body: @fn(v: ~fn()) -> ~fn(), + mut gen_body: Option<~fn(v: ~fn()) -> ~fn()>, can_not_copy: Option<util::NonCopyable>, mut consumed: bool, } @@ -188,7 +188,7 @@ pub struct TaskBuilder { pub fn task() -> TaskBuilder { TaskBuilder { opts: default_task_opts(), - gen_body: |body| body, // Identity function + gen_body: None, can_not_copy: None, mut consumed: false, } @@ -201,6 +201,7 @@ priv impl TaskBuilder { fail!(~"Cannot copy a task_builder"); // Fake move mode on self } self.consumed = true; + let gen_body = replace(&mut self.gen_body, None); let notify_chan = replace(&mut self.opts.notify_chan, None); TaskBuilder { opts: TaskOpts { @@ -209,7 +210,7 @@ priv impl TaskBuilder { notify_chan: notify_chan, sched: self.opts.sched }, - gen_body: self.gen_body, + gen_body: gen_body, can_not_copy: None, consumed: false } @@ -341,8 +342,23 @@ pub impl TaskBuilder { * generator by applying the task body which results from the * existing body generator to the new body generator. */ - fn add_wrapper(&self, wrapper: @fn(v: ~fn()) -> ~fn()) -> TaskBuilder { - let prev_gen_body = self.gen_body; + fn add_wrapper(&self, wrapper: ~fn(v: ~fn()) -> ~fn()) -> TaskBuilder { + let prev_gen_body = replace(&mut self.gen_body, None); + 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(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 + }; let notify_chan = replace(&mut self.opts.notify_chan, None); TaskBuilder { opts: TaskOpts { @@ -351,7 +367,7 @@ pub impl TaskBuilder { notify_chan: notify_chan, sched: self.opts.sched }, - gen_body: |body| { wrapper(prev_gen_body(body)) }, + gen_body: Some(next_gen_body), can_not_copy: None, .. self.consume() } @@ -370,6 +386,7 @@ pub impl TaskBuilder { * must be greater than zero. */ fn spawn(&self, f: ~fn()) { + let gen_body = replace(&mut self.gen_body, None); let notify_chan = replace(&mut self.opts.notify_chan, None); let x = self.consume(); let opts = TaskOpts { @@ -378,7 +395,15 @@ pub impl TaskBuilder { notify_chan: notify_chan, sched: x.opts.sched }; - spawn::spawn_raw(opts, (x.gen_body)(f)); + let f = match gen_body { + Some(gen) => { + gen(f) + } + None => { + f + } + }; + spawn::spawn_raw(opts, f); } /// Runs a task, while transfering ownership of one argument to the child. fn spawn_with<A:Owned>(&self, arg: A, f: ~fn(v: A)) { @@ -1201,3 +1226,12 @@ fn test_spawn_thread_on_demand() { port.recv(); } + +#[test] +fn test_simple_newsched_spawn() { + use rt::run_in_newsched_task; + + do run_in_newsched_task { + spawn(||()) + } +} diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index c71f7d26d40..118c4cc2312 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -531,6 +531,34 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) } pub fn spawn_raw(opts: TaskOpts, f: ~fn()) { + use rt::*; + + match context() { + OldTaskContext => { + spawn_raw_oldsched(opts, f) + } + TaskContext => { + spawn_raw_newsched(opts, f) + } + SchedulerContext => { + fail!(~"can't spawn from scheduler context") + } + GlobalContext => { + fail!(~"can't spawn from global context") + } + } +} + +fn spawn_raw_newsched(opts: TaskOpts, f: ~fn()) { + use rt::sched::*; + + let mut sched = local_sched::take(); + let task = ~Task::new(&mut sched.stack_pool, f); + sched.schedule_new_task(task); +} + +fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) { + let (child_tg, ancestors, is_main) = gen_child_taskgroup(opts.linked, opts.supervised); |
