about summary refs log tree commit diff
path: root/src/rt/rust_scheduler.cpp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-04-03 20:29:12 -0700
committerBrian Anderson <banderson@mozilla.com>2012-04-03 20:30:01 -0700
commite325146eb436c4995385d8220ff7ac3a4a5f62ab (patch)
tree999875912f33a00906c76f1eac278251bf63658a /src/rt/rust_scheduler.cpp
parentbd97ee65200966e6c3b0fb45de1fc771c3cf5f3f (diff)
parent4cf7efc8f7df215b0ff9e3ea15b7890b84db1b51 (diff)
downloadrust-e325146eb436c4995385d8220ff7ac3a4a5f62ab.tar.gz
rust-e325146eb436c4995385d8220ff7ac3a4a5f62ab.zip
Merge remote-tracking branch 'brson/mainthread'
Conflicts:
	src/rt/rust_kernel.cpp
	src/rt/rust_scheduler.cpp
	src/rt/rust_scheduler.h
Diffstat (limited to 'src/rt/rust_scheduler.cpp')
-rw-r--r--src/rt/rust_scheduler.cpp42
1 files changed, 31 insertions, 11 deletions
diff --git a/src/rt/rust_scheduler.cpp b/src/rt/rust_scheduler.cpp
index af52b48f985..1b5978b5cfe 100644
--- a/src/rt/rust_scheduler.cpp
+++ b/src/rt/rust_scheduler.cpp
@@ -7,15 +7,18 @@
 
 rust_scheduler::rust_scheduler(rust_kernel *kernel,
                                size_t num_threads,
-                               rust_sched_id id) :
+                               rust_sched_id id,
+                               bool allow_exit,
+                               rust_sched_launcher_factory *launchfac) :
     kernel(kernel),
     live_threads(num_threads),
     live_tasks(0),
-    num_threads(num_threads),
     cur_thread(0),
+    may_exit(allow_exit),
+    num_threads(num_threads),
     id(id)
 {
-    create_task_threads();
+    create_task_threads(launchfac);
 }
 
 rust_scheduler::~rust_scheduler() {
@@ -23,10 +26,9 @@ rust_scheduler::~rust_scheduler() {
 }
 
 rust_sched_launcher *
-rust_scheduler::create_task_thread(int id) {
-    rust_sched_launcher *thread =
-        new (kernel, "rust_thread_sched_launcher")
-        rust_thread_sched_launcher(this, id);
+rust_scheduler::create_task_thread(rust_sched_launcher_factory *launchfac,
+                                   int id) {
+    rust_sched_launcher *thread = launchfac->create(this, id);
     KLOG(kernel, kern, "created task thread: " PTR ", id: %d",
           thread, id);
     return thread;
@@ -39,11 +41,11 @@ rust_scheduler::destroy_task_thread(rust_sched_launcher *thread) {
 }
 
 void
-rust_scheduler::create_task_threads() {
+rust_scheduler::create_task_threads(rust_sched_launcher_factory *launchfac) {
     KLOG(kernel, kern, "Using %d scheduler threads.", num_threads);
 
     for(size_t i = 0; i < num_threads; ++i) {
-        threads.push(create_task_thread(i));
+        threads.push(create_task_thread(launchfac, i));
     }
 }
 
@@ -100,12 +102,11 @@ rust_scheduler::release_task() {
     {
         scoped_lock with(lock);
         live_tasks--;
-        if (live_tasks == 0) {
+        if (live_tasks == 0 && may_exit) {
             need_exit = true;
         }
     }
     if (need_exit) {
-        // There are no more tasks on this scheduler. Time to leave
         exit();
     }
 }
@@ -136,3 +137,22 @@ rust_scheduler::release_task_thread() {
         kernel->release_scheduler_id(id);
     }
 }
+
+void
+rust_scheduler::allow_exit() {
+    bool need_exit = false;
+    {
+        scoped_lock with(lock);
+        may_exit = true;
+        need_exit = live_tasks == 0;
+    }
+    if (need_exit) {
+        exit();
+    }
+}
+
+void
+rust_scheduler::disallow_exit() {
+    scoped_lock with(lock);
+    may_exit = false;
+}