Fixed deadlock caused by the message pump not being notified of new message sends.

This commit is contained in:
Michael Bebenita 2010-09-15 11:56:45 -07:00
parent 91b4a0c9f8
commit 1bd331b7aa
5 changed files with 36 additions and 5 deletions

View File

@ -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;

View File

@ -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++

View File

@ -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.
*/

View File

@ -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);
}
};
//

View File

@ -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.