fix: Crash when closing providers too quickly
This commit is contained in:
parent
4b6a75fb60
commit
4b8e275254
@ -102,16 +102,20 @@ namespace hex {
|
|||||||
static void collectGarbage();
|
static void collectGarbage();
|
||||||
|
|
||||||
static size_t getRunningTaskCount();
|
static size_t getRunningTaskCount();
|
||||||
|
static size_t getRunningBackgroundTaskCount();
|
||||||
static std::list<std::shared_ptr<Task>> &getRunningTasks();
|
static std::list<std::shared_ptr<Task>> &getRunningTasks();
|
||||||
|
|
||||||
static void doLater(const std::function<void()> &function);
|
static void doLater(const std::function<void()> &function);
|
||||||
static void runDeferredCalls();
|
static void runDeferredCalls();
|
||||||
|
|
||||||
|
static void runWhenTasksFinished(const std::function<void()> &function);
|
||||||
private:
|
private:
|
||||||
static std::mutex s_deferredCallsMutex;
|
static std::mutex s_deferredCallsMutex;
|
||||||
|
|
||||||
static std::list<std::shared_ptr<Task>> s_tasks;
|
static std::list<std::shared_ptr<Task>> s_tasks;
|
||||||
static std::list<std::shared_ptr<Task>> s_taskQueue;
|
static std::list<std::shared_ptr<Task>> s_taskQueue;
|
||||||
static std::list<std::function<void()>> s_deferredCalls;
|
static std::list<std::function<void()>> s_deferredCalls;
|
||||||
|
static std::list<std::function<void()>> s_tasksFinishedCallbacks;
|
||||||
|
|
||||||
static std::mutex s_queueMutex;
|
static std::mutex s_queueMutex;
|
||||||
static std::condition_variable s_jobCondVar;
|
static std::condition_variable s_jobCondVar;
|
||||||
|
@ -17,8 +17,8 @@ namespace hex::magic {
|
|||||||
|
|
||||||
bool compile();
|
bool compile();
|
||||||
std::string getDescription(const std::vector<u8> &data);
|
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(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);
|
||||||
|
|
||||||
}
|
}
|
@ -322,7 +322,9 @@ namespace hex {
|
|||||||
provider->close();
|
provider->close();
|
||||||
EventManager::post<EventProviderClosed>(provider);
|
EventManager::post<EventProviderClosed>(provider);
|
||||||
|
|
||||||
delete provider;
|
TaskManager::runWhenTasksFinished([provider] {
|
||||||
|
delete provider;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
prv::Provider* createProvider(const std::string &unlocalizedName, bool skipLoadInterface) {
|
prv::Provider* createProvider(const std::string &unlocalizedName, bool skipLoadInterface) {
|
||||||
|
@ -12,6 +12,7 @@ namespace hex {
|
|||||||
|
|
||||||
std::list<std::shared_ptr<Task>> TaskManager::s_tasks, TaskManager::s_taskQueue;
|
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_deferredCalls;
|
||||||
|
std::list<std::function<void()>> TaskManager::s_tasksFinishedCallbacks;
|
||||||
|
|
||||||
std::mutex TaskManager::s_queueMutex;
|
std::mutex TaskManager::s_queueMutex;
|
||||||
std::condition_variable TaskManager::s_jobCondVar;
|
std::condition_variable TaskManager::s_jobCondVar;
|
||||||
@ -238,8 +239,16 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TaskManager::collectGarbage() {
|
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(); });
|
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() {
|
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) {
|
void TaskManager::doLater(const std::function<void()> &function) {
|
||||||
std::scoped_lock lock(s_deferredCallsMutex);
|
std::scoped_lock lock(s_deferredCallsMutex);
|
||||||
@ -270,4 +287,10 @@ namespace hex {
|
|||||||
s_deferredCalls.clear();
|
s_deferredCalls.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskManager::runWhenTasksFinished(const std::function<void()> &function) {
|
||||||
|
std::scoped_lock lock(s_deferredCallsMutex);
|
||||||
|
|
||||||
|
s_tasksFinishedCallbacks.push_back(function);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -225,7 +225,8 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
while (clipper.Step())
|
while (clipper.Step())
|
||||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
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) {
|
switch (level) {
|
||||||
using enum pl::core::LogConsole::Level;
|
using enum pl::core::LogConsole::Level;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user