1
0
mirror of synced 2025-01-31 03:53:44 +01:00

fix: Crash when closing providers too quickly

This commit is contained in:
WerWolv 2022-12-27 11:35:20 +01:00
parent 4b6a75fb60
commit 4b8e275254
5 changed files with 35 additions and 5 deletions

View File

@ -102,16 +102,20 @@ namespace hex {
static void collectGarbage();
static size_t getRunningTaskCount();
static size_t getRunningBackgroundTaskCount();
static std::list<std::shared_ptr<Task>> &getRunningTasks();
static void doLater(const std::function<void()> &function);
static void runDeferredCalls();
static void runWhenTasksFinished(const std::function<void()> &function);
private:
static std::mutex s_deferredCallsMutex;
static std::list<std::shared_ptr<Task>> s_tasks;
static std::list<std::shared_ptr<Task>> s_taskQueue;
static std::list<std::function<void()>> s_deferredCalls;
static std::list<std::function<void()>> s_tasksFinishedCallbacks;
static std::mutex s_queueMutex;
static std::condition_variable s_jobCondVar;

View File

@ -17,8 +17,8 @@ namespace hex::magic {
bool compile();
std::string getDescription(const std::vector<u8> &data);
std::string getDescription(prv::Provider *provider, size_t size = 5_MiB);
std::string getDescription(prv::Provider *provider, size_t size = 100_KiB);
std::string getMIMEType(const std::vector<u8> &data);
std::string getMIMEType(prv::Provider *provider, size_t size = 5_MiB);
std::string getMIMEType(prv::Provider *provider, size_t size = 100_KiB);
}

View File

@ -322,7 +322,9 @@ namespace hex {
provider->close();
EventManager::post<EventProviderClosed>(provider);
delete provider;
TaskManager::runWhenTasksFinished([provider] {
delete provider;
});
}
prv::Provider* createProvider(const std::string &unlocalizedName, bool skipLoadInterface) {

View File

@ -12,6 +12,7 @@ namespace hex {
std::list<std::shared_ptr<Task>> TaskManager::s_tasks, TaskManager::s_taskQueue;
std::list<std::function<void()>> TaskManager::s_deferredCalls;
std::list<std::function<void()>> TaskManager::s_tasksFinishedCallbacks;
std::mutex TaskManager::s_queueMutex;
std::condition_variable TaskManager::s_jobCondVar;
@ -238,8 +239,16 @@ namespace hex {
}
void TaskManager::collectGarbage() {
std::unique_lock lock(s_queueMutex);
std::unique_lock lock1(s_queueMutex);
std::unique_lock lock2(s_deferredCallsMutex);
std::erase_if(s_tasks, [](const auto &task) { return task->isFinished() && !task->hadException(); });
if (s_tasks.empty()) {
for (auto &call : s_tasksFinishedCallbacks)
call();
s_tasksFinishedCallbacks.clear();
}
}
std::list<std::shared_ptr<Task>> &TaskManager::getRunningTasks() {
@ -254,6 +263,14 @@ namespace hex {
});
}
size_t TaskManager::getRunningBackgroundTaskCount() {
std::unique_lock lock(s_queueMutex);
return std::count_if(s_tasks.begin(), s_tasks.end(), [](const auto &task){
return task->isBackgroundTask();
});
}
void TaskManager::doLater(const std::function<void()> &function) {
std::scoped_lock lock(s_deferredCallsMutex);
@ -270,4 +287,10 @@ namespace hex {
s_deferredCalls.clear();
}
void TaskManager::runWhenTasksFinished(const std::function<void()> &function) {
std::scoped_lock lock(s_deferredCallsMutex);
s_tasksFinishedCallbacks.push_back(function);
}
}

View File

@ -225,7 +225,8 @@ namespace hex::plugin::builtin {
while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
const auto &[level, message] = console[i];
auto [level, message] = console[i];
std::replace_if(message.begin(), message.end(), [](char c) { return !std::isprint(c); }, ' ');
switch (level) {
using enum pl::core::LogConsole::Level;