moved glob_match into task, was only used there

some optimizations for matching task names, regex is so slow
fixed deadlock in git_submodule_adder, removing instrumentation also removed a critical scope for the lock object
simplified parallel_tasks, doesn't need all that stuff
moved translations to its own step for now, parallel_tasks doesn't support having both super and non-super tasks
moved add_tasks() inside try/catch, can bail out
This commit is contained in:
isanae
2020-12-03 17:45:35 -05:00
parent c991239088
commit 5e64f08418
7 changed files with 91 additions and 106 deletions
+2 -2
View File
@@ -4,7 +4,7 @@
#include "../net.h"
#include "../core/conf.h"
#include "../core/ini.h"
#include "../tasks/tasks.h"
#include "../tasks/task_manager.h"
#include "../tools/tools.h"
#include "../utility/threading.h"
@@ -14,7 +14,7 @@ namespace mob
BOOL WINAPI signal_handler(DWORD) noexcept
{
gcx().debug(context::generic, "caught sigint");
task::interrupt_all();
task_manager::instance().interrupt_all();
return TRUE;
}
+4 -4
View File
@@ -115,8 +115,7 @@ void add_tasks()
.add_task<mo>("modorganizer-installer_ncc")
.add_task<mo>("modorganizer-installer_wizard")
.add_task<mo>("modorganizer-bsa_extractor")
.add_task<mo>("modorganizer-plugin_python")
.add_task<translations>();
.add_task<mo>("modorganizer-plugin_python");
add_task<parallel_tasks>()
.add_task<mo>({"modorganizer-tool_configurator", "pycfg"})
@@ -130,6 +129,7 @@ void add_tasks()
.add_task<mo>({"modorganizer-preview_dds", "ddspreview"})
.add_task<mo>({"modorganizer", "organizer"});
add_task<translations>();
add_task<installer>();
}
@@ -210,10 +210,10 @@ int run(const std::vector<std::string>& args)
font_restorer fr;
curl_init curl;
add_tasks();
try
{
add_tasks();
auto c = handle_command_line(args);
if (!c)
return 1;
+68 -52
View File
@@ -110,11 +110,6 @@ void task::add_name(std::string s)
names_.push_back(s);
}
void task::interrupt_all()
{
task_manager::instance().interrupt_all();
}
const std::string& task::name() const
{
return names_[0];
@@ -126,19 +121,78 @@ const std::vector<std::string>& task::names() const
}
bool task::name_matches(std::string_view pattern) const
{
if (pattern == "super")
return is_super();
else if (pattern.find('*') != std::string::npos)
return name_matches_glob(pattern);
else
return name_matches_string(pattern);
}
bool task::name_matches_glob(std::string_view pattern) const
{
try
{
std::string fixed_pattern(pattern);
fixed_pattern = replace_all(fixed_pattern, "*", ".*");
fixed_pattern = replace_all(fixed_pattern, "_", "-");
std::regex re(fixed_pattern, std::regex::icase);
for (auto&& n : names_)
{
std::string fixed_name(n);
fixed_name = replace_all(fixed_name, "_", "-");
if (std::regex_match(fixed_name, re))
return true;
}
return false;
}
catch(std::exception&)
{
u8cerr
<< "bad glob '" << pattern << "'\n"
<< "globs are actually bastardized regexes where '*' is "
<< "replaced by '.*', so don't push it\n";
throw bailed();
}
}
bool task::name_matches_string(std::string_view pattern) const
{
for (auto&& n : names_)
{
if (mob::glob_match(pattern, n))
if (strings_match(n, pattern))
return true;
}
if (pattern == "super" && is_super())
return true;
return false;
}
bool task::strings_match(std::string_view a, std::string_view b) const
{
if (a.size() != b.size())
return false;
for (std::size_t i=0; i<a.size(); ++i)
{
if ((a[i] == '-' || a[i] == '_') && (b[i] == '-' || b[i] == '_'))
continue;
const auto ac = static_cast<unsigned char>(a[i]);
const auto bc = static_cast<unsigned char>(b[i]);
if (std::tolower(ac) != std::tolower(bc))
return false;
}
return true;
}
void task::threaded_run(std::string thread_name, std::function<void ()> f)
{
try
@@ -171,7 +225,7 @@ void task::threaded_run(std::string thread_name, std::function<void ()> f)
gcx().error(context::generic,
"{} bailed out, interrupting all tasks", name());
interrupt_all();
task_manager::instance().interrupt_all();
}
catch(interrupted)
{
@@ -423,7 +477,10 @@ void parallel_tasks::add_task(std::unique_ptr<task> t)
if (!children_.empty() && children_[0]->is_super() != t->is_super())
{
gcx().bail_out(context::generic,
"parallel task can't mix super and non-super tasks");
"parallel task can't mix super and non-super tasks: "
"{} super={}, {} super={}",
children_[0]->name(), children_[0]->is_super(),
t->name(), t->is_super());
}
children_.push_back(std::move(t));
@@ -460,7 +517,6 @@ void parallel_tasks::run()
join();
}
void parallel_tasks::interrupt()
{
for (auto& t : children_)
@@ -475,44 +531,4 @@ void parallel_tasks::join()
threads_.clear();
}
void parallel_tasks::fetch()
{
// no-op
}
void parallel_tasks::build_and_install()
{
threaded_run(name(), [&]
{
for (auto& t : children_)
{
threads_.push_back(start_thread([&]
{
t->run();
}));
}
});
}
void parallel_tasks::do_fetch()
{
}
void parallel_tasks::do_build_and_install()
{
}
void parallel_tasks::do_clean(clean)
{
for (auto& t : children_)
{
threads_.push_back(start_thread([&]
{
t->clean_task();
}));
}
join();
}
} // namespace
+12 -14
View File
@@ -28,11 +28,13 @@ public:
task& operator=(const task&) = delete;
virtual ~task();
static void interrupt_all();
virtual bool enabled() const;
const std::string& name() const;
const std::vector<std::string>& names() const;
// case insensitive, underscores and dashes are equivalent; gets converted
// to a regex where * becomes .*
//
bool name_matches(std::string_view pattern) const;
virtual fs::path get_source_path() const = 0;
@@ -45,10 +47,6 @@ public:
virtual void interrupt();
virtual void join();
virtual void clean_task();
virtual void fetch();
virtual void build_and_install();
protected:
template <class... Names>
task(std::string name, Names&&... names)
@@ -99,6 +97,14 @@ private:
clean make_clean_flags() const;
void run_tool_impl(tool* t);
bool name_matches_glob(std::string_view pattern) const;
bool name_matches_string(std::string_view pattern) const;
bool strings_match(std::string_view a, std::string_view b) const;
void clean_task();
void fetch();
void build_and_install();
};
@@ -186,16 +192,8 @@ public:
void interrupt() override;
void join() override;
void fetch() override;
void build_and_install() override;
std::vector<task*> children() const override;
protected:
void do_fetch() override;
void do_build_and_install() override;
void do_clean(clean c) override;
private:
std::vector<std::unique_ptr<task>> children_;
std::vector<std::thread> threads_;
+5 -3
View File
@@ -808,9 +808,11 @@ void git_submodule_adder::thread_fun()
{
while (!quit_)
{
std::unique_lock lk(sleeper_.m);
sleeper_.cv.wait(lk, [&]{ return sleeper_.ready; });
sleeper_.ready = false;
{
std::unique_lock lk(sleeper_.m);
sleeper_.cv.wait(lk, [&]{ return sleeper_.ready; });
sleeper_.ready = false;
}
if (quit_)
break;
-26
View File
@@ -5,32 +5,6 @@
namespace mob
{
bool glob_match(std::string_view pattern, std::string_view s)
{
try
{
std::string fixed_pattern(pattern);
fixed_pattern = replace_all(fixed_pattern, "*", ".*");
fixed_pattern = replace_all(fixed_pattern, "_", "-");
std::string fixed_string(s);
fixed_string = replace_all(fixed_string, "_", "-");
std::regex re(fixed_pattern, std::regex::icase);
return std::regex_match(fixed_string, re);
}
catch(std::exception&)
{
u8cerr
<< "bad glob '" << pattern << "'\n"
<< "globs are actually bastardized regexes where '*' is "
<< "replaced by '.*', so don't push it\n";
throw bailed();
}
}
std::string replace_all(
std::string s, const std::string& from, const std::string& to)
{
-5
View File
@@ -15,11 +15,6 @@ enum class encodings
};
// case insensitive, underscores and dashes are equivalent; gets converted to
// a regex where * becomes .*
//
bool glob_match(std::string_view pattern, std::string_view s);
// replaces all instances of `from` by `to`, returns a copy
//
std::string replace_all(