Fixed deadlock in the scheduler caused by condition variables.
This commit is contained in:
parent
4641fcef61
commit
5917ca3519
@ -262,8 +262,6 @@ void rust_dom::send_message(rust_message *message) {
|
||||
this);
|
||||
A(this, message->dom == this, "Message owned by non-local domain.");
|
||||
_incoming_message_queue.enqueue(message);
|
||||
_incoming_message_pending.signal();
|
||||
_progress.signal();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -398,9 +396,11 @@ rust_dom::start_main_loop()
|
||||
"all tasks are blocked, waiting for progress ...");
|
||||
if (_log.is_tracing(rust_log::TASK))
|
||||
log_state();
|
||||
_progress.wait();
|
||||
log(rust_log::TASK,
|
||||
"progress made, resuming ...");
|
||||
"all tasks are blocked, scheduler yielding ...");
|
||||
sync::yield();
|
||||
log(rust_log::TASK,
|
||||
"scheduler resuming ...");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -450,7 +450,14 @@ rust_dom::start_main_loop()
|
||||
}
|
||||
|
||||
if (_incoming_message_queue.is_empty()) {
|
||||
_incoming_message_pending.wait();
|
||||
log(rust_log::DOM,
|
||||
"waiting for %d dead tasks to become dereferenced, "
|
||||
"scheduler yielding ...",
|
||||
dead_tasks.length());
|
||||
if (_log.is_tracing(rust_log::TASK)) {
|
||||
log_state();
|
||||
}
|
||||
sync::yield();
|
||||
} else {
|
||||
drain_incoming_message_queue();
|
||||
}
|
||||
|
@ -34,13 +34,10 @@ struct rust_dom
|
||||
rust_task *curr_task;
|
||||
int rval;
|
||||
|
||||
condition_variable _progress;
|
||||
|
||||
hash_map<rust_task *, rust_proxy<rust_task> *> _task_proxies;
|
||||
hash_map<rust_port *, rust_proxy<rust_port> *> _port_proxies;
|
||||
|
||||
// Incoming messages from other domains.
|
||||
condition_variable _incoming_message_pending;
|
||||
lock_free_queue _incoming_message_queue;
|
||||
|
||||
#ifndef __WIN32__
|
||||
|
@ -38,6 +38,7 @@ extern "C" {
|
||||
#error "Platform not supported."
|
||||
#endif
|
||||
|
||||
#include "sync/sync.h"
|
||||
#include "sync/condition_variable.h"
|
||||
|
||||
#ifndef __i386__
|
||||
|
@ -556,9 +556,6 @@ rust_task::wakeup(rust_cond *from)
|
||||
A(dom, cond == from, "Cannot wake up blocked task on wrong condition.");
|
||||
|
||||
transition(&dom->blocked_tasks, &dom->running_tasks);
|
||||
// TODO: Signaling every time the task is awaken is kind of silly,
|
||||
// do this a nicer way.
|
||||
dom->_progress.signal();
|
||||
I(dom, cond == from);
|
||||
cond = NULL;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user