mirror of
https://github.com/Zygo/bees.git
synced 2025-05-18 05:45:45 +02:00
task: rescue post-exec queue on Task destruction
task1.append(task2) is supposed to run task2 after task1 is executed; however, if task1 was just executed, and its last reference was owned by a TaskConsumer, then task2 will be appended to a Task that will never run again. A similar problem arises in Exclusion, which can cause blocked tasks to occasionally be dropped without executing them. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
2aafa802a9
commit
46a38fe016
17
lib/task.cc
17
lib/task.cc
@ -55,8 +55,8 @@ namespace crucible {
|
|||||||
/// Tasks to be executed after the current task is executed
|
/// Tasks to be executed after the current task is executed
|
||||||
list<TaskStatePtr> m_post_exec_queue;
|
list<TaskStatePtr> m_post_exec_queue;
|
||||||
|
|
||||||
/// Incremented by run() and append(). Decremented by exec().
|
/// Set by run() and append(). Cleared by exec().
|
||||||
size_t m_run_count = 0;
|
bool m_run_now = false;
|
||||||
|
|
||||||
/// Set when task starts execution by exec().
|
/// Set when task starts execution by exec().
|
||||||
/// Cleared when exec() ends.
|
/// Cleared when exec() ends.
|
||||||
@ -221,6 +221,9 @@ namespace crucible {
|
|||||||
TaskState::~TaskState()
|
TaskState::~TaskState()
|
||||||
{
|
{
|
||||||
--s_instance_count;
|
--s_instance_count;
|
||||||
|
unique_lock<mutex> lock(m_mutex);
|
||||||
|
// If any dependent Tasks were appended since the last exec, run them now
|
||||||
|
TaskState::rescue_queue(m_post_exec_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskState::TaskState(string title, function<void()> exec_fn) :
|
TaskState::TaskState(string title, function<void()> exec_fn) :
|
||||||
@ -275,8 +278,8 @@ namespace crucible {
|
|||||||
{
|
{
|
||||||
THROW_CHECK0(invalid_argument, task);
|
THROW_CHECK0(invalid_argument, task);
|
||||||
PairLock lock(m_mutex, task->m_mutex);
|
PairLock lock(m_mutex, task->m_mutex);
|
||||||
if (!task->m_run_count) {
|
if (!task->m_run_now) {
|
||||||
++task->m_run_count;
|
task->m_run_now = true;
|
||||||
append_nolock(task);
|
append_nolock(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,7 +295,7 @@ namespace crucible {
|
|||||||
append_nolock(shared_from_this());
|
append_nolock(shared_from_this());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
--m_run_count;
|
m_run_now = false;
|
||||||
m_is_running = true;
|
m_is_running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,10 +338,10 @@ namespace crucible {
|
|||||||
TaskState::run()
|
TaskState::run()
|
||||||
{
|
{
|
||||||
unique_lock<mutex> lock(m_mutex);
|
unique_lock<mutex> lock(m_mutex);
|
||||||
if (m_run_count) {
|
if (m_run_now) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
++m_run_count;
|
m_run_now = true;
|
||||||
TaskMasterState::push_back(shared_from_this());
|
TaskMasterState::push_back(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user