working on fixing task memory leaks

This commit is contained in:
HJfod 2024-04-22 15:21:44 +03:00
parent 3b58ed3ae2
commit ab0aa47495
6 changed files with 60 additions and 14 deletions

View file

@ -6,6 +6,8 @@
#include "../loader/Loader.hpp"
namespace geode {
extern std::atomic_size_t TASK_HANDLE_COUNT;
template <std::move_constructible T, std::move_constructible P = std::monostate>
class [[nodiscard]] Task final {
public:
@ -54,11 +56,12 @@ namespace geode {
std::optional<T> m_resultValue;
bool m_finalEventPosted = false;
std::unique_ptr<void, void(*)(void*)> m_mapListener = { nullptr, +[](void*) {} };
const char* m_whatIsThis = "Unk";
class PrivateMarker final {};
static std::shared_ptr<Handle> create() {
return std::make_shared<Handle>(PrivateMarker());
static std::shared_ptr<Handle> create(const char* whatIsThis) {
return std::make_shared<Handle>(PrivateMarker(), whatIsThis);
}
bool is(Status status) {
@ -70,7 +73,18 @@ namespace geode {
friend class Task;
public:
Handle(PrivateMarker) {}
std::string fmt() {
if (!this) return "null";
return fmt::format("({} @ {})", fmt::ptr(this), m_whatIsThis);
}
Handle(PrivateMarker, const char* whatIsThis) {
m_whatIsThis = whatIsThis;
log::info("create handle {}, {}", this->fmt(), ++TASK_HANDLE_COUNT);
}
~Handle() {
log::info("destroy handle {}, {}", this->fmt(), --TASK_HANDLE_COUNT);
}
};
class Event final : public geode::Event {
@ -171,16 +185,27 @@ namespace geode {
friend class Task;
public:
Task() : m_handle(nullptr) {}
Task() : m_handle(nullptr) {
log::info("create Task with handle {}", m_handle->fmt());
}
~Task() {
log::info("destroy Task with handle {}", m_handle->fmt());
}
Task(Task const& other) : m_handle(other.m_handle) {}
Task(Task&& other) : m_handle(std::move(other.m_handle)) {}
Task(Task const& other) : m_handle(other.m_handle) {
log::info("copy Task with handle {}", m_handle->fmt());
}
Task(Task&& other) : m_handle(std::move(other.m_handle)) {
log::info("move Task with handle {}", m_handle->fmt());
}
Task& operator=(Task const& other) {
m_handle = other.m_handle;
log::info("copy assign Task with handle {}", m_handle->fmt());
return *this;
}
Task& operator=(Task&& other) {
m_handle = std::move(other.m_handle);
log::info("move assign Task with handle {}", m_handle->fmt());
return *this;
}
@ -223,12 +248,12 @@ namespace geode {
}
static Task immediate(T value) {
auto task = Task(Handle::create());
auto task = Task(Handle::create("Task::immediate"));
Task::finish(task.m_handle, std::move(value));
return task;
}
static Task run(Run&& body) {
auto task = Task(Handle::create());
auto task = Task(Handle::create("Task::run"));
std::thread([handle = std::weak_ptr(task.m_handle), body = std::move(body)] {
utils::thread::setName(fmt::format("Task @{}", fmt::ptr(handle.lock())));
auto result = body(
@ -252,7 +277,7 @@ namespace geode {
return task;
}
static Task runWithCallback(RunWithCallback&& body) {
auto task = Task(Handle::create());
auto task = Task(Handle::create("Task::runWithCallback"));
std::thread([handle = std::weak_ptr(task.m_handle), body = std::move(body)] {
utils::thread::setName(fmt::format("Task (w/ callback) @{}", fmt::ptr(handle.lock())));
body(
@ -283,7 +308,7 @@ namespace geode {
using T2 = decltype(resultMapper(std::declval<T*>()));
using P2 = decltype(progressMapper(std::declval<P*>()));
auto task = Task<T2, P2>(Task<T2, P2>::Handle::create());
auto task = Task<T2, P2>(Task<T2, P2>::Handle::create("Task::map"));
// Lock the current task until we have managed to create our new one
std::unique_lock<std::recursive_mutex> lock(m_handle->m_mutex);

View file

@ -125,6 +125,9 @@ public:
m_cache.add(Query(query), ServerRequest<Value>(f));
return f;
}
size_t size() {
return m_cache.size();
}
void limit(size_t size) {
m_cache.limit(size);
}

View file

@ -187,8 +187,6 @@ void ModsLayer::gotoTab(ModListSource* src) {
if (m_currentSource) {
m_lists.at(m_currentSource)->removeFromParent();
}
// Update current source
m_currentSource = src;
// Lazily create new list and add it to UI
if (!m_lists.contains(src)) {
@ -201,6 +199,9 @@ void ModsLayer::gotoTab(ModListSource* src) {
else {
this->addChild(m_lists.at(src));
}
// Update current source
m_currentSource = src;
// Update the state of the current list
m_lists.at(m_currentSource)->updateSize(m_bigView);
@ -266,7 +267,8 @@ void ModsLayer::onBack(CCObject*) {
CCDirector::get()->replaceScene(CCTransitionFade::create(.5f, MenuLayer::scene(false)));
// To avoid memory overloading, clear caches after leaving the layer
server::clearServerCaches();
server::clearServerCaches(true);
clearAllModListSourceCaches();
}
void ModsLayer::onGoToPage(CCObject*) {

View file

@ -376,3 +376,17 @@ void ModPackListSource::setModTags(std::unordered_set<std::string> const& set) {
bool ModPackListSource::wantsRestart() const {
return false;
}
void clearAllModListSourceCaches() {
InstalledModListSource::get(false)->clearCache();
InstalledModListSource::get(true)->clearCache();
ServerModListSource::get(ServerModListType::Download)->clearCache();
ServerModListSource::get(ServerModListType::Featured)->clearCache();
ServerModListSource::get(ServerModListType::Trending)->clearCache();
ServerModListSource::get(ServerModListType::Recent)->clearCache();
ModPackListSource::get()->clearCache();
}
std::atomic_size_t geode::TASK_HANDLE_COUNT = 0;

View file

@ -173,3 +173,5 @@ public:
bool wantsRestart() const override;
};
void clearAllModListSourceCaches();

View file

@ -1,4 +1,4 @@
#define GEODE_UI_TEST
// #define GEODE_UI_TEST
#ifdef GEODE_UI_TEST
#include <Geode/modify/MenuLayer.hpp>