1
0
mirror of synced 2024-11-28 09:30:51 +01:00

fix: Various pattern execution race conditions

This commit is contained in:
WerWolv 2023-05-12 15:46:13 +02:00
parent 0a7a190b04
commit aaeebd3fe9
5 changed files with 45 additions and 40 deletions

View File

@ -272,7 +272,7 @@ namespace hex {
* @brief Provides access to the current provider's pattern language runtime's lock * @brief Provides access to the current provider's pattern language runtime's lock
* @return Lock * @return Lock
*/ */
std::scoped_lock<std::mutex> getRuntimeLock(); std::mutex& getRuntimeLock();
/** /**
* @brief Configures the pattern language runtime using ImHex's default settings * @brief Configures the pattern language runtime using ImHex's default settings

View File

@ -265,10 +265,10 @@ namespace hex {
return *runtime; return *runtime;
} }
std::scoped_lock<std::mutex> getRuntimeLock() { std::mutex& getRuntimeLock() {
static std::mutex runtimeLock; static std::mutex runtimeLock;
return std::scoped_lock(runtimeLock); return runtimeLock;
} }
void configureRuntime(pl::PatternLanguage &runtime, prv::Provider *provider) { void configureRuntime(pl::PatternLanguage &runtime, prv::Provider *provider) {

View File

@ -1162,7 +1162,7 @@ namespace hex::plugin::builtin {
} }
void process() override { void process() override {
auto lock = ContentRegistry::PatternLanguage::getRuntimeLock(); auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
const auto &outVars = runtime.getOutVariables(); const auto &outVars = runtime.getOutVariables();

View File

@ -37,7 +37,7 @@ namespace hex::plugin::builtin {
if (!runtime.arePatternsValid()) { if (!runtime.arePatternsValid()) {
this->m_patternDrawer.draw({}); this->m_patternDrawer.draw({});
} else { } else {
auto lock = ContentRegistry::PatternLanguage::getRuntimeLock(); auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
if (this->m_shouldReset) { if (this->m_shouldReset) {
this->m_patternDrawer.reset(); this->m_patternDrawer.reset();

View File

@ -141,6 +141,8 @@ namespace hex::plugin::builtin {
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1);
{
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
if (runtime.isRunning()) { if (runtime.isRunning()) {
if (ImGui::IconButton(ICON_VS_DEBUG_STOP, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) if (ImGui::IconButton(ICON_VS_DEBUG_STOP, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed)))
@ -172,6 +174,7 @@ namespace hex::plugin::builtin {
runtime.getCreatedPatternCount(), runtime.getCreatedPatternCount(),
runtime.getMaximumPatternCount()); runtime.getMaximumPatternCount());
} }
}
if (this->m_textEditor.IsTextChanged()) { if (this->m_textEditor.IsTextChanged()) {
this->m_hasUnevaluatedChanges = true; this->m_hasUnevaluatedChanges = true;
@ -407,6 +410,7 @@ namespace hex::plugin::builtin {
} }
void ViewPatternEditor::drawSectionSelector(ImVec2 size, std::map<u64, pl::api::Section> &sections) { void ViewPatternEditor::drawSectionSelector(ImVec2 size, std::map<u64, pl::api::Section> &sections) {
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
if (ImGui::BeginTable("##sections_table", 3, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, size)) { if (ImGui::BeginTable("##sections_table", 3, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, size)) {
@ -640,6 +644,8 @@ namespace hex::plugin::builtin {
} }
void ViewPatternEditor::evaluatePattern(const std::string &code, prv::Provider *provider) { void ViewPatternEditor::evaluatePattern(const std::string &code, prv::Provider *provider) {
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
this->m_runningEvaluators++; this->m_runningEvaluators++;
*this->m_executionDone = false; *this->m_executionDone = false;
@ -650,12 +656,12 @@ namespace hex::plugin::builtin {
EventManager::post<EventHighlightingChanged>(); EventManager::post<EventHighlightingChanged>();
TaskManager::createTask("hex.builtin.view.pattern_editor.evaluating", TaskManager::NoProgress, [this, code, provider](auto &task) {
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
ContentRegistry::PatternLanguage::configureRuntime(runtime, provider); ContentRegistry::PatternLanguage::configureRuntime(runtime, provider);
TaskManager::createTask("hex.builtin.view.pattern_editor.evaluating", TaskManager::NoProgress, [this, code, &runtime](auto &task) {
auto lock = ContentRegistry::PatternLanguage::getRuntimeLock();
task.setInterruptCallback([&runtime] { runtime.abort(); }); task.setInterruptCallback([&runtime] { runtime.abort(); });
std::map<std::string, pl::core::Token::Literal> envVars; std::map<std::string, pl::core::Token::Literal> envVars;
@ -725,9 +731,6 @@ namespace hex::plugin::builtin {
}); });
EventManager::subscribe<EventProviderOpened>(this, [this](prv::Provider *provider) { EventManager::subscribe<EventProviderOpened>(this, [this](prv::Provider *provider) {
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
ContentRegistry::PatternLanguage::configureRuntime(runtime, provider);
TaskManager::createBackgroundTask("Analyzing file content", [this, provider](auto &) { TaskManager::createBackgroundTask("Analyzing file content", [this, provider](auto &) {
if (!this->m_autoLoadPatterns) if (!this->m_autoLoadPatterns)
return; return;
@ -737,7 +740,7 @@ namespace hex::plugin::builtin {
*this->m_sourceCode = this->m_textEditor.GetText(); *this->m_sourceCode = this->m_textEditor.GetText();
} }
auto lock = ContentRegistry::PatternLanguage::getRuntimeLock(); auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto& runtime = ContentRegistry::PatternLanguage::getRuntime(); auto& runtime = ContentRegistry::PatternLanguage::getRuntime();
ContentRegistry::PatternLanguage::configureRuntime(runtime, provider); ContentRegistry::PatternLanguage::configureRuntime(runtime, provider);
@ -939,6 +942,7 @@ namespace hex::plugin::builtin {
if (this->m_runningEvaluators != 0) if (this->m_runningEvaluators != 0)
return std::nullopt; return std::nullopt;
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
std::optional<ImColor> color; std::optional<ImColor> color;
@ -958,6 +962,7 @@ namespace hex::plugin::builtin {
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) { ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
hex::unused(data, size); hex::unused(data, size);
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
auto patterns = runtime.getPatternsAtAddress(address); auto patterns = runtime.getPatternsAtAddress(address);