about summary refs log tree commit diff
path: root/src/libcore/task
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-04-19 15:57:50 -0700
committerbors <bors@rust-lang.org>2013-04-19 15:57:50 -0700
commit6510fd92544467a03df93b5124644976aa79f964 (patch)
tree58b8f87b6432f171e4dd7d0b82cc9adbb4938b83 /src/libcore/task
parentbffe23b0cfee2e6957a81a98f8c8a885522e3444 (diff)
parent7270fadfccb8f7b767bf45bda106a55b6a874c03 (diff)
downloadrust-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.rs48
-rw-r--r--src/libcore/task/spawn.rs28
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);