about summary refs log tree commit diff
path: root/src/rt/rust_task.cpp
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-08-16 16:39:47 -0700
committerEric Holk <eholk@mozilla.com>2011-08-16 16:47:40 -0700
commit8686645aad315467c97f457e8330696d88a4f9a0 (patch)
treec2a054c5c9d10249cdd56f6b7e5a714833732f16 /src/rt/rust_task.cpp
parent07225e2169d3a96bed28110ff976a6752c0ec0a8 (diff)
downloadrust-8686645aad315467c97f457e8330696d88a4f9a0.tar.gz
rust-8686645aad315467c97f457e8330696d88a4f9a0.zip
New channel-based task status notifications.
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 8ef83488513..c877d5e9941 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -80,6 +80,10 @@ rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
     LOGPTR(sched, "new task", (uintptr_t)this);
     DLOG(sched, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *this);
 
+    assert((void*)this == (void*)&user);
+
+    user.notify_enabled = 0;
+
     stk = new_stk(sched, this, 0);
     rust_sp = stk->limit;
 }
@@ -89,6 +93,19 @@ rust_task::~rust_task()
     DLOG(sched, task, "~rust_task %s @0x%" PRIxPTR ", refcnt=%d",
          name, (uintptr_t)this, ref_count);
 
+    if(user.notify_enabled) {
+        rust_chan *target =
+            get_chan_by_handle(&user.notify_chan);
+        if(target) {
+            task_notification msg;
+            msg.id = id;
+            msg.result = failed ? tr_failure : tr_success;
+
+            target->send(&msg);
+            target->deref();
+        }
+    }
+
     kernel->release_task_id(id);
 
     /* FIXME: tighten this up, there are some more
@@ -400,8 +417,11 @@ rust_task::free(void *p, bool is_gc)
 
 void
 rust_task::transition(rust_task_list *src, rust_task_list *dst) {
-    I(sched, !sched->lock.lock_held_by_current_thread());
-    scoped_lock with(sched->lock);
+    bool unlock = false;
+    if(!sched->lock.lock_held_by_current_thread()) {
+        unlock = true;
+        sched->lock.lock();
+    }
     DLOG(sched, task,
          "task %s " PTR " state change '%s' -> '%s' while in '%s'",
          name, (uintptr_t)this, src->name, dst->name, state->name);
@@ -409,6 +429,8 @@ rust_task::transition(rust_task_list *src, rust_task_list *dst) {
     src->remove(this);
     dst->append(this);
     state = dst;
+    if(unlock)
+        sched->lock.unlock();
 }
 
 void