Skip to content

Commit

Permalink
Fixed deadlock caused by the message pump not being notified of new m…
Browse files Browse the repository at this point in the history
…essage sends.
  • Loading branch information
mbebenita committed Sep 16, 2010
1 parent 91b4a0c commit 1bd331b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/rt/rust_dom.cpp
Expand Up @@ -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;
Expand Down
21 changes: 18 additions & 3 deletions src/rt/rust_kernel.cpp
Expand Up @@ -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();
}

Expand Down Expand Up @@ -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++
Expand Down
11 changes: 11 additions & 0 deletions src/rt/rust_kernel.h
Expand Up @@ -9,6 +9,7 @@
*/

class rust_kernel;
class rust_message;

template <typename T> class
rust_handle :
Expand Down Expand Up @@ -90,6 +91,16 @@ class rust_kernel : public rust_thread {

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.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/rt/rust_message.h
Expand Up @@ -114,6 +114,11 @@ class rust_message_queue : public lock_free_queue<rust_message*>,
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);
}
};

//
Expand Down
2 changes: 1 addition & 1 deletion src/rt/sync/lock_free_queue.h
Expand Up @@ -120,7 +120,7 @@ class lock_free_queue {
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.
Expand Down

0 comments on commit 1bd331b

Please sign in to comment.