about summary refs log tree commit diff
path: root/src/rt/rust_dom.cpp
diff options
context:
space:
mode:
authorMichael Bebenita <mbebenita@mozilla.com>2010-08-17 23:47:11 -0700
committerMichael Bebenita <mbebenita@mozilla.com>2010-08-17 23:49:57 -0700
commita4b8c74f9f6e41f40b30cf4ef49ea42a2cee9b4f (patch)
tree049269b2a2fd77d754e39d0eeeda1f26e8dc121b /src/rt/rust_dom.cpp
parent2c1ec6771bd09266308686ab13ca32e2aa73da49 (diff)
downloadrust-a4b8c74f9f6e41f40b30cf4ef49ea42a2cee9b4f.tar.gz
rust-a4b8c74f9f6e41f40b30cf4ef49ea42a2cee9b4f.zip
Added simple deadlock detection in the scheduler.
Diffstat (limited to 'src/rt/rust_dom.cpp')
-rw-r--r--src/rt/rust_dom.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp
index 67a1be3644d..ce6bebf3a8c 100644
--- a/src/rt/rust_dom.cpp
+++ b/src/rt/rust_dom.cpp
@@ -368,6 +368,31 @@ rust_dom::schedule_task() {
     return NULL;
 }
 
+/**
+ * Checks for simple deadlocks.
+ */
+bool
+rust_dom::is_deadlocked() {
+    if (_live_domains.size() != 1) {
+        // We cannot tell if we are deadlocked if other domains exists.
+        return false;
+    }
+
+    if (running_tasks.length() != 0) {
+        // We are making progress and therefore we are not deadlocked.
+        return false;
+    }
+
+    if (_incoming_message_queue.is_empty() && blocked_tasks.length() > 0) {
+        // We have no messages to process, no running tasks to schedule
+        // and some blocked tasks therefore we are likely in a deadlock.
+        log_state();
+        return true;
+    }
+
+    return false;
+}
+
 void
 rust_dom::log_all_state() {
     for (uint32_t i = 0; i < _live_domains.size(); i++) {
@@ -427,6 +452,8 @@ rust_dom::start_main_loop()
     logptr("exit-task glue", root_crate->get_exit_task_glue());
 
     while (n_live_tasks() > 0) {
+        A(this, is_deadlocked() == false, "deadlock");
+
         drain_incoming_message_queue();
 
         rust_task *scheduled_task = schedule_task();