diff options
| author | Michael Bebenita <[email protected]> | 2010-09-15 11:56:45 -0700 |
|---|---|---|
| committer | Michael Bebenita <[email protected]> | 2010-09-16 00:51:03 -0700 |
| commit | 1bd331b7aaa24245f86868305ab64600683a41e1 (patch) | |
| tree | 1b088c433bc95ee416eefe502b0dca866b5dead6 /src/rt | |
| parent | Add beginnings of a fuzzer to rustboot. (diff) | |
| download | rust-1bd331b7aaa24245f86868305ab64600683a41e1.tar.xz rust-1bd331b7aaa24245f86868305ab64600683a41e1.zip | |
Fixed deadlock caused by the message pump not being notified of new message sends.
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/rust_dom.cpp | 2 | ||||
| -rw-r--r-- | src/rt/rust_kernel.cpp | 21 | ||||
| -rw-r--r-- | src/rt/rust_kernel.h | 11 | ||||
| -rw-r--r-- | src/rt/rust_message.h | 5 | ||||
| -rw-r--r-- | src/rt/sync/lock_free_queue.h | 2 |
5 files changed, 36 insertions, 5 deletions
diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp index d3b5d2ce..45279551 100644 --- a/src/rt/rust_dom.cpp +++ b/src/rt/rust_dom.cpp @@ -314,7 +314,7 @@ rust_dom::start_main_loop() { } log(rust_log::TASK, "all tasks are blocked, scheduler yielding ..."); - sync::yield(); + sync::sleep(100); log(rust_log::TASK, "scheduler resuming ..."); continue; diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index ef4220f9..0dc1369d 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -164,9 +164,7 @@ void rust_kernel::terminate_kernel_loop() { log(rust_log::KERN, "terminating kernel loop"); _interrupt_kernel_loop = true; - _kernel_lock.lock(); - _kernel_lock.signal_all(); - _kernel_lock.unlock(); + signal_kernel_lock(); join(); } @@ -217,6 +215,23 @@ rust_kernel::free_handles(hash_map<T*, rust_handle<T>* > &map) { } } +void +rust_kernel::notify_message_enqueued(rust_message_queue *queue, + rust_message *message) { + // The message pump needs to handle this message if the queue is not + // associated with a domain, therefore signal the message pump. + if (queue->is_associated() == false) { + signal_kernel_lock(); + } +} + +void +rust_kernel::signal_kernel_lock() { + _kernel_lock.lock(); + _kernel_lock.signal_all(); + _kernel_lock.unlock(); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index f85d55ac..3ad7b396 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -9,6 +9,7 @@ */ class rust_kernel; +class rust_message; template <typename T> class rust_handle : @@ -90,6 +91,16 @@ public: bool is_deadlocked(); + void signal_kernel_lock(); + + /** + * Notifies the kernel whenever a message has been enqueued . This gives + * the kernel the opportunity to wake up the message pump thread if the + * message queue is not associated. + */ + void + notify_message_enqueued(rust_message_queue *queue, rust_message *message); + /** * Blocks until all domains have terminated. */ diff --git a/src/rt/rust_message.h b/src/rt/rust_message.h index c342e3e4..e9ce94bf 100644 --- a/src/rt/rust_message.h +++ b/src/rt/rust_message.h @@ -114,6 +114,11 @@ public: bool is_associated() { return this->dom_handle != NULL; } + + void enqueue(rust_message* message) { + lock_free_queue<rust_message*>::enqueue(message); + kernel->notify_message_enqueued(this, message); + } }; // diff --git a/src/rt/sync/lock_free_queue.h b/src/rt/sync/lock_free_queue.h index ac0c5b04..1c760bff 100644 --- a/src/rt/sync/lock_free_queue.h +++ b/src/rt/sync/lock_free_queue.h @@ -120,7 +120,7 @@ public: return head.node == tail.node; } - void enqueue(T value) { + virtual void enqueue(T value) { // Create a new node to be inserted in the linked list, and set the // next node to NULL. |