about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-05-31 23:25:13 -0700
committerBrian Anderson <banderson@mozilla.com>2012-05-31 23:47:52 -0700
commit4c8bc19ad2d5b9a51febf916a2a93b07da146385 (patch)
tree279186722b249a2736f754007497b9ff66fab813
parente47962f6a9fdbac2054c15fea8953c2338e8e115 (diff)
downloadrust-4c8bc19ad2d5b9a51febf916a2a93b07da146385.tar.gz
rust-4c8bc19ad2d5b9a51febf916a2a93b07da146385.zip
rt: Refactor task failure to go through rust_task_fail
This is the place to but a breakpoint. We will raise SIGINT here
to break into the debugger.
-rw-r--r--src/rt/rust_task.cpp29
-rw-r--r--src/rt/rust_task.h15
-rw-r--r--src/rt/rust_upcall.cpp4
3 files changed, 45 insertions, 3 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 5299de0ed34..a5097dff4d0 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -75,6 +75,16 @@ rust_task::delete_this()
     sched_loop->release_task(this);
 }
 
+// All failure goes through me. Put your breakpoints here!
+extern "C" void
+rust_task_fail(rust_task *task,
+               char const *expr,
+               char const *file,
+               size_t line) {
+    assert(task != NULL);
+    task->begin_failure(expr, file, line);
+}
+
 struct spawn_args {
     rust_task *task;
     spawn_fn f;
@@ -264,6 +274,25 @@ bool rust_task_is_unwinding(rust_task *rt) {
 void
 rust_task::fail() {
     // See note in ::kill() regarding who should call this.
+    fail(NULL, NULL, 0);
+}
+
+void
+rust_task::fail(char const *expr, char const *file, size_t line) {
+    rust_task_fail(this, expr, file, line);
+}
+
+// Called only by rust_task_fail
+void
+rust_task::begin_failure(char const *expr, char const *file, size_t line) {
+
+    if (expr) {
+        // FIXME: Change this message to be
+        // 'task failed at ...'
+        LOG_ERR(this, task, "upcall fail '%s', %s:%" PRIdPTR,
+                expr, file, line);
+    }
+
     DLOG(sched_loop, task, "task %s @0x%" PRIxPTR " failing", name, this);
     backtrace();
     unwinding = true;
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 69a56e425de..4ad13472024 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -97,6 +97,12 @@ struct task_notification {
     task_result result; // task_result
 };
 
+extern "C" void
+rust_task_fail(rust_task *task,
+               char const *expr,
+               char const *file,
+               size_t line);
+
 struct
 rust_task : public kernel_owned<rust_task>, rust_cond
 {
@@ -181,11 +187,19 @@ private:
                     rust_cond *cond, const char* cond_name);
 
     bool must_fail_from_being_killed_unlocked();
+    // Called by rust_task_fail to unwind on failure
+    void begin_failure(char const *expr,
+                       char const *file,
+                       size_t line);
 
     friend void task_start_wrapper(spawn_args *a);
     friend void cleanup_task(cleanup_args *a);
     friend void reset_stack_limit_on_c_stack(reset_args *a);
     friend void new_stack_slow(new_stack_args *a);
+    friend void rust_task_fail(rust_task *task,
+                               char const *expr,
+                               char const *file,
+                               size_t line);
 
 public:
 
@@ -231,6 +245,7 @@ public:
 
     // Fail self, assuming caller-on-stack is this task.
     void fail();
+    void fail(char const *expr, char const *file, size_t line);
     void conclude_failure();
     void fail_parent();
 
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index ac11ee7a26b..21df231aee7 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -116,9 +116,7 @@ extern "C" CDECL void
 upcall_s_fail(s_fail_args *args) {
     rust_task *task = rust_get_current_task();
     LOG_UPCALL_ENTRY(task);
-    LOG_ERR(task, upcall, "upcall fail '%s', %s:%" PRIdPTR,
-            args->expr, args->file, args->line);
-    task->fail();
+    task->fail(args->expr, args->file, args->line);
 }
 
 extern "C" CDECL void