2020-04-29 22:10:55 -04:00
|
|
|
#include "pch.h"
|
|
|
|
|
#include "task.h"
|
2020-05-02 04:03:20 -04:00
|
|
|
#include "../conf.h"
|
|
|
|
|
#include "../op.h"
|
2020-05-03 03:46:58 -04:00
|
|
|
#include "../tools/tools.h"
|
2020-04-29 22:10:55 -04:00
|
|
|
|
2020-05-02 03:12:34 -04:00
|
|
|
namespace mob
|
2020-04-29 22:10:55 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
class interrupted {};
|
|
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<task>> g_tasks;
|
|
|
|
|
std::mutex task::interrupt_mutex_;
|
|
|
|
|
|
|
|
|
|
void add_task(std::unique_ptr<task> t)
|
|
|
|
|
{
|
|
|
|
|
g_tasks.push_back(std::move(t));
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 14:07:45 -04:00
|
|
|
void list_tasks(bool err)
|
|
|
|
|
{
|
|
|
|
|
for (auto&& t : g_tasks)
|
|
|
|
|
{
|
|
|
|
|
if (err)
|
|
|
|
|
std::cerr << " - " << join(t->names(), ", ") << "\n";
|
|
|
|
|
else
|
|
|
|
|
std::cout << " - " << join(t->names(), ", ") << "\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
task* find_task(const std::string& name)
|
2020-04-29 22:10:55 -04:00
|
|
|
{
|
|
|
|
|
for (auto&& t : g_tasks)
|
|
|
|
|
{
|
2020-05-03 03:32:40 -04:00
|
|
|
for (auto&& n : t->names())
|
2020-04-29 22:10:55 -04:00
|
|
|
{
|
2020-05-03 03:32:40 -04:00
|
|
|
if (n == name)
|
2020-05-06 04:09:03 -04:00
|
|
|
return t.get();
|
2020-04-29 22:10:55 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 14:07:45 -04:00
|
|
|
std::cout << "task " << name << " not found\n";
|
|
|
|
|
std::cout << "valid tasks:\n";
|
|
|
|
|
list_tasks(true);
|
2020-04-29 22:10:55 -04:00
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
throw bailed("");
|
2020-04-29 22:10:55 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 13:39:47 -04:00
|
|
|
void run_tasks(const std::set<task*> tasks)
|
2020-05-06 04:09:03 -04:00
|
|
|
{
|
|
|
|
|
for (auto* t : tasks)
|
|
|
|
|
t->fetch();
|
|
|
|
|
|
|
|
|
|
for (auto* t : tasks)
|
|
|
|
|
{
|
|
|
|
|
t->join();
|
|
|
|
|
t->build_and_install();
|
|
|
|
|
t->join();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 13:39:47 -04:00
|
|
|
void gather_super_tasks(std::set<task*>& tasks)
|
|
|
|
|
{
|
|
|
|
|
for (auto& t : g_tasks)
|
|
|
|
|
{
|
|
|
|
|
if (t->is_super())
|
|
|
|
|
tasks.insert(t.get());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
void run_task(const std::string& name)
|
|
|
|
|
{
|
|
|
|
|
run_tasks({find_task(name)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void run_tasks(const std::vector<std::string>& names)
|
2020-05-06 03:39:45 -04:00
|
|
|
{
|
|
|
|
|
if (names.empty())
|
2020-05-06 04:09:03 -04:00
|
|
|
return;
|
2020-05-06 03:39:45 -04:00
|
|
|
|
|
|
|
|
if (names.size() == 1)
|
|
|
|
|
gcx().debug(context::generic, "specified task: " + names[0]);
|
|
|
|
|
else
|
|
|
|
|
gcx().debug(context::generic, "specified tasks: " + join(names, " "));
|
|
|
|
|
|
2020-05-06 13:39:47 -04:00
|
|
|
std::set<task*> tasks;
|
2020-05-06 04:09:03 -04:00
|
|
|
for (auto&& name : names)
|
2020-05-06 13:39:47 -04:00
|
|
|
{
|
|
|
|
|
if (name == "super")
|
|
|
|
|
gather_super_tasks(tasks);
|
|
|
|
|
else
|
|
|
|
|
tasks.insert(find_task(name));
|
|
|
|
|
}
|
2020-05-06 03:39:45 -04:00
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
run_tasks(tasks);
|
2020-05-06 03:39:45 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
void run_all_tasks()
|
2020-04-29 22:10:55 -04:00
|
|
|
{
|
2020-05-06 13:39:47 -04:00
|
|
|
std::set<task*> tasks;
|
2020-04-29 22:10:55 -04:00
|
|
|
for (auto&& t : g_tasks)
|
2020-05-06 13:39:47 -04:00
|
|
|
tasks.insert(t.get());
|
2020-05-06 03:39:45 -04:00
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
run_tasks(tasks);
|
2020-04-29 22:10:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-05-03 03:32:40 -04:00
|
|
|
task::task(std::vector<std::string> names)
|
2020-05-04 05:38:23 -04:00
|
|
|
: names_(std::move(names)), interrupted_(false)
|
2020-05-03 03:32:40 -04:00
|
|
|
{
|
2020-05-04 05:38:23 -04:00
|
|
|
contexts_.push_back(std::make_unique<thread_context>(
|
|
|
|
|
std::this_thread::get_id(), context(name())));
|
2020-05-03 03:32:40 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-29 22:10:55 -04:00
|
|
|
task::~task()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
join();
|
|
|
|
|
}
|
|
|
|
|
catch(bailed)
|
|
|
|
|
{
|
|
|
|
|
// ignore
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 13:39:47 -04:00
|
|
|
bool task::is_super() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-04 05:38:23 -04:00
|
|
|
const context& task::cx() const
|
|
|
|
|
{
|
|
|
|
|
static const context bad("?");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(contexts_mutex_);
|
|
|
|
|
|
|
|
|
|
for (auto& td : contexts_)
|
|
|
|
|
{
|
|
|
|
|
if (td->tid == std::this_thread::get_id())
|
|
|
|
|
return td->cx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bad;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 12:29:38 -04:00
|
|
|
void task::add_name(std::string s)
|
|
|
|
|
{
|
|
|
|
|
names_.push_back(s);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-29 22:10:55 -04:00
|
|
|
void task::interrupt_all()
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(interrupt_mutex_);
|
|
|
|
|
for (auto&& t : g_tasks)
|
|
|
|
|
t->interrupt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::string& task::name() const
|
|
|
|
|
{
|
2020-05-03 03:32:40 -04:00
|
|
|
return names_[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::vector<std::string>& task::names() const
|
|
|
|
|
{
|
|
|
|
|
return names_;
|
2020-04-29 22:10:55 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-04 05:38:23 -04:00
|
|
|
void task::threaded_run(std::string thread_name, std::function<void ()> f)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(contexts_mutex_);
|
|
|
|
|
|
|
|
|
|
contexts_.push_back(std::make_unique<thread_context>(
|
|
|
|
|
std::this_thread::get_id(), context(thread_name)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
guard g([&]
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(contexts_mutex_);
|
|
|
|
|
|
|
|
|
|
for (auto itor=contexts_.begin(); itor!=contexts_.end(); ++itor)
|
|
|
|
|
{
|
|
|
|
|
if ((*itor)->tid == std::this_thread::get_id())
|
|
|
|
|
{
|
|
|
|
|
contexts_.erase(itor);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
f();
|
|
|
|
|
}
|
|
|
|
|
catch(bailed e)
|
|
|
|
|
{
|
|
|
|
|
error(name() + " bailed out, interrupting all tasks");
|
|
|
|
|
interrupt_all();
|
|
|
|
|
}
|
|
|
|
|
catch(interrupted)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
catch(std::exception& e)
|
|
|
|
|
{
|
|
|
|
|
error(name() + " uncaught exception: " + e.what());
|
|
|
|
|
interrupt_all();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-29 22:10:55 -04:00
|
|
|
void task::run()
|
|
|
|
|
{
|
2020-05-04 05:38:23 -04:00
|
|
|
cx().info(context::generic, "running task");
|
2020-04-29 22:10:55 -04:00
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
fetch();
|
|
|
|
|
join();
|
2020-05-02 04:03:20 -04:00
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
build_and_install();
|
|
|
|
|
join();
|
2020-05-04 03:02:33 -04:00
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
cx().info(context::generic, "task completed");
|
2020-04-29 22:10:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void task::interrupt()
|
|
|
|
|
{
|
2020-05-04 05:38:23 -04:00
|
|
|
std::scoped_lock lock(tools_mutex_);
|
2020-04-29 22:10:55 -04:00
|
|
|
|
|
|
|
|
interrupted_ = true;
|
2020-05-04 05:38:23 -04:00
|
|
|
|
|
|
|
|
for (auto* t : tools_)
|
|
|
|
|
t->interrupt();
|
2020-04-29 22:10:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void task::join()
|
|
|
|
|
{
|
|
|
|
|
if (thread_.joinable())
|
|
|
|
|
thread_.join();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void task::fetch()
|
|
|
|
|
{
|
2020-05-06 04:09:03 -04:00
|
|
|
thread_ = std::thread([&]
|
|
|
|
|
{
|
|
|
|
|
threaded_run(name(), [&]
|
|
|
|
|
{
|
|
|
|
|
if (conf::rebuild())
|
|
|
|
|
clean_for_rebuild();
|
2020-04-29 22:10:55 -04:00
|
|
|
|
2020-05-06 04:09:03 -04:00
|
|
|
check_interrupted();
|
|
|
|
|
|
|
|
|
|
cx().info(context::generic, "fetching");
|
|
|
|
|
do_fetch();
|
|
|
|
|
|
|
|
|
|
check_interrupted();
|
|
|
|
|
|
2020-05-06 05:22:42 -04:00
|
|
|
if (!get_source_path().empty())
|
|
|
|
|
{
|
2020-05-06 07:43:15 -04:00
|
|
|
cx().debug(context::generic, "patching");
|
|
|
|
|
|
2020-05-06 05:22:42 -04:00
|
|
|
run_tool(patcher()
|
|
|
|
|
.task(name())
|
|
|
|
|
.root(get_source_path()));
|
|
|
|
|
}
|
2020-05-06 04:09:03 -04:00
|
|
|
|
|
|
|
|
check_interrupted();
|
|
|
|
|
});
|
|
|
|
|
});
|
2020-04-29 22:10:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void task::build_and_install()
|
|
|
|
|
{
|
2020-05-06 04:09:03 -04:00
|
|
|
thread_ = std::thread([&]
|
|
|
|
|
{
|
|
|
|
|
threaded_run(name(), [&]
|
|
|
|
|
{
|
|
|
|
|
check_interrupted();
|
|
|
|
|
|
|
|
|
|
cx().info(context::generic, "build and install");
|
|
|
|
|
do_build_and_install();
|
|
|
|
|
|
|
|
|
|
check_interrupted();
|
|
|
|
|
});
|
|
|
|
|
});
|
2020-04-29 22:10:55 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-04 06:22:35 -04:00
|
|
|
void task::clean_for_rebuild()
|
2020-05-02 04:03:20 -04:00
|
|
|
{
|
2020-05-06 04:09:03 -04:00
|
|
|
cx().info(context::rebuild, "cleaning");
|
2020-05-04 06:22:35 -04:00
|
|
|
do_clean_for_rebuild();
|
2020-05-02 04:03:20 -04:00
|
|
|
}
|
2020-04-29 22:10:55 -04:00
|
|
|
|
|
|
|
|
void task::check_interrupted()
|
|
|
|
|
{
|
|
|
|
|
if (interrupted_)
|
|
|
|
|
throw interrupted();
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-04 05:38:23 -04:00
|
|
|
void task::run_tool_impl(tool* t)
|
2020-05-03 03:32:40 -04:00
|
|
|
{
|
2020-05-04 05:38:23 -04:00
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(tools_mutex_);
|
|
|
|
|
tools_.push_back(t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
guard g([&]
|
|
|
|
|
{
|
|
|
|
|
std::scoped_lock lock(tools_mutex_);
|
|
|
|
|
|
|
|
|
|
for (auto itor=tools_.begin(); itor!=tools_.end(); ++itor)
|
|
|
|
|
{
|
|
|
|
|
if (*itor == t)
|
|
|
|
|
{
|
|
|
|
|
tools_.erase(itor);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
cx().debug(context::generic, "running tool " + t->name());
|
|
|
|
|
|
|
|
|
|
context cxcopy(cx());
|
2020-05-03 05:42:56 -04:00
|
|
|
|
2020-05-03 03:32:40 -04:00
|
|
|
check_interrupted();
|
2020-05-04 05:38:23 -04:00
|
|
|
t->run(cxcopy);
|
2020-05-03 03:32:40 -04:00
|
|
|
check_interrupted();
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-29 22:10:55 -04:00
|
|
|
} // namespace
|