1
0
mirror of https://github.com/Zygo/bees.git synced 2025-05-17 13:25:45 +02:00

task: allow external access to Task print function

This enables bees' thread introspection to use task descriptions in
status and log messages.

BeesNote will be calling Task::current_task() from non-Task contexts,
which means we need to allow Task's shared state pointer to be null.
Remove some asserts that will ruin our day in that case.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
Zygo Blaxell 2018-01-20 13:51:05 -05:00
parent e970ac6c02
commit 3f60a0efde
2 changed files with 37 additions and 16 deletions

View File

@ -32,13 +32,22 @@ namespace crucible {
// schedule Task before other queued tasks
void run_earlier() const;
// describe Task as text
ostream &print(ostream &os) const;
// Returns currently executing task if called from exec_fn.
// Usually used to reschedule the currently executing Task.
static Task current_task();
// Ordering for containers
bool operator<(const Task &that) const;
// Null test
operator bool() const;
};
ostream &operator<<(ostream &os, const Task &task);
class TaskMaster {
public:
// Blocks until the running thread count reaches this number

View File

@ -15,7 +15,7 @@
namespace crucible {
using namespace std;
static thread_local weak_ptr<TaskState> s_current_task_wp;
static thread_local weak_ptr<TaskState> tl_current_task_wp;
class TaskState : public enable_shared_from_this<TaskState> {
const function<void()> m_exec_fn;
@ -28,7 +28,7 @@ namespace crucible {
void exec();
ostream &print(ostream &os);
TaskId id();
TaskId id() const;
};
atomic<TaskId> TaskState::s_next_id;
@ -87,9 +87,9 @@ namespace crucible {
THROW_CHECK0(invalid_argument, m_exec_fn);
weak_ptr<TaskState> this_task_wp = shared_from_this();
Cleanup cleaner([&]() {
swap(this_task_wp, s_current_task_wp);
swap(this_task_wp, tl_current_task_wp);
});
swap(this_task_wp, s_current_task_wp);
swap(this_task_wp, tl_current_task_wp);
m_exec_fn();
}
@ -101,7 +101,7 @@ namespace crucible {
}
TaskId
TaskState::id()
TaskState::id() const
{
return m_id;
}
@ -126,7 +126,6 @@ namespace crucible {
void
TaskMasterState::push_back(shared_ptr<TaskState> task)
{
assert(task);
THROW_CHECK0(runtime_error, task);
s_tms->start_stop_threads();
unique_lock<mutex> lock(s_tms->m_mutex);
@ -137,7 +136,6 @@ namespace crucible {
void
TaskMasterState::push_front(shared_ptr<TaskState> task)
{
assert(task);
THROW_CHECK0(runtime_error, task);
s_tms->start_stop_threads();
unique_lock<mutex> lock(s_tms->m_mutex);
@ -224,42 +222,51 @@ namespace crucible {
Task::Task(shared_ptr<TaskState> pts) :
m_task_state(pts)
{
assert(m_task_state);
}
Task::Task(function<void()> exec_fn, function<ostream&(ostream &)> print_fn) :
m_task_state(make_shared<TaskState>(exec_fn, print_fn))
{
assert(m_task_state);
}
void
Task::run() const
{
assert(m_task_state);
THROW_CHECK0(runtime_error, m_task_state);
TaskMasterState::push_back(m_task_state);
}
void
Task::run_earlier() const
{
assert(m_task_state);
THROW_CHECK0(runtime_error, m_task_state);
TaskMasterState::push_front(m_task_state);
}
Task
Task::current_task()
{
return Task(s_current_task_wp.lock());
return Task(tl_current_task_wp.lock());
}
ostream &
Task::print(ostream &os) const
{
THROW_CHECK0(runtime_error, m_task_state);
return m_task_state->print(os);
}
ostream &
operator<<(ostream &os, const Task &task)
{
return task.print(os);
};
TaskId
Task::id() const
{
if (m_task_state) {
return m_task_state->id();
}
return 0;
THROW_CHECK0(runtime_error, m_task_state);
return m_task_state->id();
}
bool
@ -268,6 +275,11 @@ namespace crucible {
return id() < that.id();
}
Task::operator bool() const
{
return !!m_task_state;
}
shared_ptr<TaskState>
TaskConsumer::current_task_locked()
{