about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorMichael Bebenita <mbebenita@mozilla.com>2010-07-28 15:17:30 -0700
committerGraydon Hoare <graydon@mozilla.com>2010-07-28 20:30:29 -0700
commitdefd8a66eade4cb11960cf6de2b45c2f42ec3388 (patch)
treed9c2c87a2df903ba4ae3b93536805a6b2ad17c39 /src/rt
parent30b3f8a11713e32fdb0d0059141289152a46d501 (diff)
downloadrust-defd8a66eade4cb11960cf6de2b45c2f42ec3388.tar.gz
rust-defd8a66eade4cb11960cf6de2b45c2f42ec3388.zip
Rename rust_proxy_delegate to maybe_proxy, flesh out logic in it. Add strong-ref distinction on rust_proxy.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust_proxy.h47
-rw-r--r--src/rt/rust_task.cpp2
-rw-r--r--src/rt/rust_task.h5
-rw-r--r--src/rt/rust_upcall.cpp17
4 files changed, 48 insertions, 23 deletions
diff --git a/src/rt/rust_proxy.h b/src/rt/rust_proxy.h
index e2fa5e00546..bf12e1d5f0e 100644
--- a/src/rt/rust_proxy.h
+++ b/src/rt/rust_proxy.h
@@ -1,30 +1,55 @@
+#ifndef RUST_PROXY_H
+#define RUST_PROXY_H
+
 /**
  * A proxy object is a wrapper around other Rust objects. One use of the proxy
  * object is to mitigate access between tasks in different thread domains.
  */
 
-#ifndef RUST_PROXY_H
-#define RUST_PROXY_H
-
+template <typename T> struct rust_proxy;
+/**
+ * The base class of all objects that may delegate.
+ */
 template <typename T> struct
-rust_proxy_delegate : public rc_base<T> {
+maybe_proxy : public rc_base<T>, public rust_cond {
 protected:
     T *_delegate;
 public:
-    rust_proxy_delegate(T * delegate) : _delegate(delegate) {
+    maybe_proxy(T * delegate) : _delegate(delegate) {
+
+    }
+    T *delegate() {
+        return _delegate;
+    }
+    bool is_proxy() {
+        return _delegate != this;
+    }
+    rust_proxy<T> *as_proxy() {
+        return (rust_proxy<T> *) this;
+    }
+    T *as_delegate() {
+        I(_delegate->get_dom(), !is_proxy());
+        return (T *) this;
     }
-    T *delegate() { return _delegate; }
 };
 
+/**
+ * A proxy object that delegates to another.
+ */
 template <typename T> struct
-rust_proxy : public rust_proxy_delegate<T>,
+rust_proxy : public maybe_proxy<T>,
              public dom_owned<rust_proxy<T> > {
+private:
+    bool _strong;
 public:
     rust_dom *dom;
-    rust_proxy(rust_dom *dom, T *delegate) :
-        rust_proxy_delegate<T> (delegate),
-        dom(dom) {
-        delegate->ref();
+    rust_proxy(rust_dom *dom, T *delegate, bool strong) :
+        maybe_proxy<T> (delegate), _strong(strong), dom(dom) {
+        this->dom->log(rust_log::COMM,
+            "new proxy: 0x%" PRIxPTR " => 0x%" PRIxPTR, this, delegate);
+        if (strong) {
+            delegate->ref();
+        }
     }
 };
 
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 2bb0954196e..189824ac16a 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -53,7 +53,7 @@ align_down(uintptr_t sp)
 
 
 rust_task::rust_task(rust_dom *dom, rust_task *spawner) :
-    rust_proxy_delegate<rust_task>(this),
+    maybe_proxy<rust_task>(this),
     stk(new_stk(dom, 0)),
     runtime_sp(0),
     rust_sp(stk->limit),
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index a5cca2cbfc0..0c723a9dd5d 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -5,9 +5,8 @@
 #ifndef RUST_TASK_H
 #define RUST_TASK_H
 struct
-rust_task : public rust_proxy_delegate<rust_task>,
-            public dom_owned<rust_task>,
-            public rust_cond
+rust_task : public maybe_proxy<rust_task>,
+            public dom_owned<rust_task>
 {
     // Fields known to the compiler.
     stk_seg *stk;
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 77d39b859b3..e4604049c4d 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -105,7 +105,7 @@ extern "C" CDECL void upcall_del_chan(rust_task *task, rust_chan *chan) {
  */
 extern "C" CDECL rust_chan *
 upcall_clone_chan(rust_task *task,
-                  rust_proxy_delegate<rust_task> *spawnee_proxy,
+                  maybe_proxy<rust_task> *spawnee_proxy,
                   rust_chan *chan) {
     LOG_UPCALL_ENTRY(task);
     rust_task *spawnee = spawnee_proxy->delegate();
@@ -121,8 +121,8 @@ extern "C" CDECL void upcall_yield(rust_task *task) {
     task->yield(1);
 }
 
-extern "C" CDECL void upcall_join(rust_task *task,
-                                  rust_proxy_delegate<rust_task> *proxy) {
+extern "C" CDECL void
+upcall_join(rust_task *task, maybe_proxy<rust_task> *proxy) {
     LOG_UPCALL_ENTRY(task);
     task->log(rust_log::UPCALL | rust_log::COMM,
                   "join proxy 0x%" PRIxPTR " -> task = 0x%" PRIxPTR,
@@ -194,7 +194,7 @@ extern "C" CDECL void upcall_fail(rust_task *task, char const *expr,
  * Called whenever a task's ref count drops to zero.
  */
 extern "C" CDECL void
-upcall_kill(rust_task *task, rust_proxy_delegate<rust_task> *target_proxy) {
+upcall_kill(rust_task *task, maybe_proxy<rust_task> *target_proxy) {
     LOG_UPCALL_ENTRY(task);
     rust_task *target_task = target_proxy->delegate();
     if (target_proxy != target_task) {
@@ -504,7 +504,7 @@ upcall_start_task(rust_task *spawner, rust_task *task,
     return task;
 }
 
-extern "C" CDECL rust_proxy_delegate<rust_task> *
+extern "C" CDECL maybe_proxy<rust_task> *
 upcall_new_thread(rust_task *task) {
     LOG_UPCALL_ENTRY(task);
 
@@ -516,16 +516,17 @@ upcall_new_thread(rust_task *task) {
               "upcall new_thread() = dom 0x%" PRIxPTR " task 0x%" PRIxPTR,
               new_dom, new_dom->root_task);
     rust_proxy<rust_task> *proxy =
-            new (old_dom) rust_proxy<rust_task>(old_dom, new_dom->root_task);
+        new (old_dom) rust_proxy<rust_task>(old_dom,
+                                            new_dom->root_task, true);
     task->log(rust_log::UPCALL | rust_log::MEM,
               "new proxy = 0x%" PRIxPTR " -> task = 0x%" PRIxPTR,
               proxy, proxy->delegate());
     return proxy;
 }
 
-extern "C" CDECL rust_proxy_delegate<rust_task> *
+extern "C" CDECL maybe_proxy<rust_task> *
 upcall_start_thread(rust_task *spawner,
-                    rust_proxy_delegate<rust_task> *root_task_proxy,
+                    maybe_proxy<rust_task> *root_task_proxy,
     uintptr_t exit_task_glue, uintptr_t spawnee_fn, size_t callsz) {
     LOG_UPCALL_ENTRY(spawner);