[General] Fix protobuf and other memory leaks
This commit is contained in:
parent
f81a36ae3b
commit
2de95b4a3b
@ -4,6 +4,7 @@ namespace Components
|
||||
{
|
||||
bool Loader::Pregame = true;
|
||||
std::vector<Component*> Loader::Components;
|
||||
Utils::Memory::Allocator Loader::MemAllocator;
|
||||
|
||||
bool Loader::IsPregame()
|
||||
{
|
||||
@ -13,6 +14,7 @@ namespace Components
|
||||
void Loader::Initialize()
|
||||
{
|
||||
Loader::Pregame = true;
|
||||
Loader::MemAllocator.clear();
|
||||
|
||||
Loader::Register(new Flags());
|
||||
Loader::Register(new Singleton());
|
||||
@ -97,6 +99,7 @@ namespace Components
|
||||
}
|
||||
|
||||
Loader::Components.clear();
|
||||
Loader::MemAllocator.clear();
|
||||
}
|
||||
|
||||
bool Loader::PerformUnitTests()
|
||||
@ -142,4 +145,9 @@ namespace Components
|
||||
Loader::Components.push_back(component);
|
||||
}
|
||||
}
|
||||
|
||||
Utils::Memory::Allocator* Loader::GetAlloctor()
|
||||
{
|
||||
return &Loader::MemAllocator;
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,12 @@ namespace Components
|
||||
|
||||
static bool IsPregame();
|
||||
|
||||
static Utils::Memory::Allocator* GetAlloctor();
|
||||
|
||||
private:
|
||||
static bool Pregame;
|
||||
static std::vector<Component*> Components;
|
||||
static Utils::Memory::Allocator MemAllocator;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -250,6 +250,7 @@ namespace Components
|
||||
delwin(Console::InputWindow);
|
||||
delwin(Console::InfoWindow);
|
||||
endwin();
|
||||
delscreen(SP);
|
||||
|
||||
Console::OutputWindow = nullptr;
|
||||
Console::InputWindow = nullptr;
|
||||
|
@ -289,6 +289,9 @@ namespace Components
|
||||
|
||||
if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled()) // Run zonebuilder as dedi :P
|
||||
{
|
||||
// Make sure all callbacks are handled
|
||||
Dedicated::OnFrame(Steam::SteamAPI_RunCallbacks);
|
||||
|
||||
Dvar::Register<bool>("sv_lanOnly", false, Game::dvar_flag::DVAR_FLAG_NONE, "Don't act as node");
|
||||
|
||||
Utils::Hook(0x60BE98, Dedicated::InitDedicatedServer, HOOK_CALL).install()->quick();
|
||||
|
@ -23,26 +23,28 @@ namespace Components
|
||||
Discovery::IsTerminating = false;
|
||||
Discovery::Thread = std::thread([] ()
|
||||
{
|
||||
while (!Discovery::IsTerminating)
|
||||
{
|
||||
if (Discovery::IsPerforming)
|
||||
while (!Discovery::IsTerminating)
|
||||
{
|
||||
int start = Game::Sys_Milliseconds();
|
||||
if (Discovery::IsPerforming)
|
||||
{
|
||||
int start = Game::Sys_Milliseconds();
|
||||
|
||||
Logger::Print("Starting local server discovery...\n");
|
||||
Logger::Print("Starting local server discovery...\n");
|
||||
|
||||
Discovery::Challenge = Utils::Cryptography::Rand::GenerateChallenge();
|
||||
Discovery::Challenge = Utils::Cryptography::Rand::GenerateChallenge();
|
||||
|
||||
unsigned int minPort = Dvar::Var("net_discoveryPortRangeMin").get<unsigned int>();
|
||||
unsigned int maxPort = Dvar::Var("net_discoveryPortRangeMax").get<unsigned int>();
|
||||
Network::BroadcastRange(minPort, maxPort, Utils::String::VA("discovery %s", Discovery::Challenge.data()));
|
||||
unsigned int minPort = Dvar::Var("net_discoveryPortRangeMin").get<unsigned int>();
|
||||
unsigned int maxPort = Dvar::Var("net_discoveryPortRangeMax").get<unsigned int>();
|
||||
Network::BroadcastRange(minPort, maxPort, Utils::String::VA("discovery %s", Discovery::Challenge.data()));
|
||||
|
||||
Logger::Print("Discovery sent within %dms, awaiting responses...\n", Game::Sys_Milliseconds() - start);
|
||||
Logger::Print("Discovery sent within %dms, awaiting responses...\n", Game::Sys_Milliseconds() - start);
|
||||
|
||||
Discovery::IsPerforming = false;
|
||||
Discovery::IsPerforming = false;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(50ms);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(50ms);
|
||||
}
|
||||
});
|
||||
|
||||
@ -104,5 +106,7 @@ namespace Components
|
||||
{
|
||||
Discovery::Thread.join();
|
||||
}
|
||||
|
||||
Discovery::Thread = std::thread();
|
||||
}
|
||||
}
|
||||
|
@ -125,6 +125,8 @@ namespace Components
|
||||
|
||||
Logger::Print("Pipe thread terminated.\n");
|
||||
}
|
||||
|
||||
this->thread = std::thread();
|
||||
}
|
||||
|
||||
void Pipe::setName(std::string name)
|
||||
@ -138,40 +140,42 @@ namespace Components
|
||||
|
||||
void Pipe::ReceiveThread(Pipe* pipe)
|
||||
{
|
||||
if (!pipe || pipe->type != IPCTYPE_SERVER || pipe->pipe == INVALID_HANDLE_VALUE || !pipe->pipe) return;
|
||||
|
||||
if (ConnectNamedPipe(pipe->pipe, nullptr) == FALSE)
|
||||
{
|
||||
Logger::Print("Failed to initialize pipe reading.\n");
|
||||
return;
|
||||
}
|
||||
if (!pipe || pipe->type != IPCTYPE_SERVER || pipe->pipe == INVALID_HANDLE_VALUE || !pipe->pipe) return;
|
||||
|
||||
Logger::Print("Client connected to the pipe\n");
|
||||
pipe->connectCallback();
|
||||
|
||||
DWORD cbBytes;
|
||||
|
||||
while (pipe->threadAttached && pipe->pipe && pipe->pipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
BOOL bResult = ReadFile(pipe->pipe, &pipe->packet, sizeof(pipe->packet), &cbBytes, nullptr);
|
||||
|
||||
if (bResult && cbBytes)
|
||||
if (ConnectNamedPipe(pipe->pipe, nullptr) == FALSE)
|
||||
{
|
||||
if (pipe->packetCallbacks.find(pipe->packet.command) != pipe->packetCallbacks.end())
|
||||
Logger::Print("Failed to initialize pipe reading.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger::Print("Client connected to the pipe\n");
|
||||
pipe->connectCallback();
|
||||
|
||||
DWORD cbBytes;
|
||||
|
||||
while (pipe->threadAttached && pipe->pipe && pipe->pipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
BOOL bResult = ReadFile(pipe->pipe, &pipe->packet, sizeof(pipe->packet), &cbBytes, nullptr);
|
||||
|
||||
if (bResult && cbBytes)
|
||||
{
|
||||
pipe->packetCallbacks[pipe->packet.command](pipe->packet.buffer);
|
||||
if (pipe->packetCallbacks.find(pipe->packet.command) != pipe->packetCallbacks.end())
|
||||
{
|
||||
pipe->packetCallbacks[pipe->packet.command](pipe->packet.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pipe->threadAttached && pipe->pipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Logger::Print("Failed to read from client through pipe\n");
|
||||
else if (pipe->threadAttached && pipe->pipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Logger::Print("Failed to read from client through pipe\n");
|
||||
|
||||
DisconnectNamedPipe(pipe->pipe);
|
||||
ConnectNamedPipe(pipe->pipe, nullptr);
|
||||
pipe->connectCallback();
|
||||
}
|
||||
DisconnectNamedPipe(pipe->pipe);
|
||||
ConnectNamedPipe(pipe->pipe, nullptr);
|
||||
pipe->connectCallback();
|
||||
}
|
||||
|
||||
ZeroMemory(&pipe->packet, sizeof(pipe->packet));
|
||||
ZeroMemory(&pipe->packet, sizeof(pipe->packet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,25 +161,27 @@ namespace Components
|
||||
News::Terminate = false;
|
||||
News::Thread = std::thread([] ()
|
||||
{
|
||||
Localization::Set("MPUI_CHANGELOG_TEXT", Utils::Cache::GetFile("/iw4/changelog.txt"));
|
||||
|
||||
std::string data = Utils::Cache::GetFile("/iw4/motd.txt");
|
||||
|
||||
if (!data.empty())
|
||||
{
|
||||
Localization::Set("MPUI_MOTD_TEXT", data);
|
||||
}
|
||||
Localization::Set("MPUI_CHANGELOG_TEXT", Utils::Cache::GetFile("/iw4/changelog.txt"));
|
||||
|
||||
if (!Loader::PerformingUnitTests())
|
||||
{
|
||||
while (!News::Terminate)
|
||||
std::string data = Utils::Cache::GetFile("/iw4/motd.txt");
|
||||
|
||||
if (!data.empty())
|
||||
{
|
||||
News::CheckForUpdate();
|
||||
Localization::Set("MPUI_MOTD_TEXT", data);
|
||||
}
|
||||
|
||||
// Sleep for 3 minutes
|
||||
for (int i = 0; i < 180 && !News::Terminate; ++i)
|
||||
if (!Loader::PerformingUnitTests())
|
||||
{
|
||||
while (!News::Terminate)
|
||||
{
|
||||
std::this_thread::sleep_for(1s);
|
||||
News::CheckForUpdate();
|
||||
|
||||
// Sleep for 3 minutes
|
||||
for (int i = 0; i < 180 && !News::Terminate; ++i)
|
||||
{
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -195,5 +197,7 @@ namespace Components
|
||||
{
|
||||
News::Thread.join();
|
||||
}
|
||||
|
||||
News::Thread = std::thread();
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ namespace Game
|
||||
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize)
|
||||
{
|
||||
int elSize = DB_GetXAssetSizeHandlers[type]();
|
||||
XAssetHeader poolEntry = { Utils::Memory::Allocate(newSize * elSize) };
|
||||
XAssetHeader poolEntry = { Components::Loader::GetAlloctor()->allocate(newSize * elSize) };
|
||||
DB_XAssetPool[type] = poolEntry;
|
||||
g_poolSize[type] = newSize;
|
||||
return poolEntry;
|
||||
|
@ -42,6 +42,8 @@ namespace Main
|
||||
void Uninitialize()
|
||||
{
|
||||
Components::Loader::Uninitialize();
|
||||
Utils::Cache::Uninitialize();
|
||||
google::protobuf::ShutdownProtobufLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,26 +7,32 @@ namespace Steam
|
||||
std::map<uint64_t, Callbacks::Base*> Callbacks::ResultHandlers;
|
||||
std::vector<Callbacks::Result> Callbacks::Results;
|
||||
std::vector<Callbacks::Base*> Callbacks::CallbackList;
|
||||
std::recursive_mutex Callbacks::Mutex;
|
||||
|
||||
uint64_t Callbacks::RegisterCall()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Callbacks::Mutex);
|
||||
Callbacks::Calls[++Callbacks::CallID] = false;
|
||||
return Callbacks::CallID;
|
||||
}
|
||||
|
||||
void Callbacks::RegisterCallback(Callbacks::Base* handler, int callback)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Callbacks::Mutex);
|
||||
handler->SetICallback(callback);
|
||||
Callbacks::CallbackList.push_back(handler);
|
||||
}
|
||||
|
||||
void Callbacks::RegisterCallResult(uint64_t call, Callbacks::Base* result)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Callbacks::Mutex);
|
||||
Callbacks::ResultHandlers[call] = result;
|
||||
}
|
||||
|
||||
void Callbacks::ReturnCall(void* data, int size, int type, uint64_t call)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Callbacks::Mutex);
|
||||
|
||||
Callbacks::Result result;
|
||||
|
||||
Callbacks::Calls[call] = true;
|
||||
@ -41,7 +47,12 @@ namespace Steam
|
||||
|
||||
void Callbacks::RunCallbacks()
|
||||
{
|
||||
for (auto result : Callbacks::Results)
|
||||
std::lock_guard<std::recursive_mutex> _(Callbacks::Mutex);
|
||||
|
||||
auto results = Callbacks::Results;
|
||||
Callbacks::Results.clear();
|
||||
|
||||
for (auto result : results)
|
||||
{
|
||||
if (Callbacks::ResultHandlers.find(result.call) != Callbacks::ResultHandlers.end())
|
||||
{
|
||||
@ -61,6 +72,19 @@ namespace Steam
|
||||
::Utils::Memory::Free(result.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Callbacks::Uninitialize()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Callbacks::Mutex);
|
||||
|
||||
for (auto result : Callbacks::Results)
|
||||
{
|
||||
if (result.data)
|
||||
{
|
||||
::Utils::Memory::Free(result.data);
|
||||
}
|
||||
}
|
||||
|
||||
Callbacks::Results.clear();
|
||||
}
|
||||
@ -111,6 +135,7 @@ namespace Steam
|
||||
void SteamAPI_Shutdown()
|
||||
{
|
||||
Proxy::Uninititalize();
|
||||
Callbacks::Uninitialize();
|
||||
}
|
||||
|
||||
void SteamAPI_UnregisterCallResult()
|
||||
|
@ -81,12 +81,15 @@ namespace Steam
|
||||
static void ReturnCall(void* data, int size, int type, uint64_t call);
|
||||
static void RunCallbacks();
|
||||
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
static uint64_t CallID;
|
||||
static std::map<uint64_t, bool> Calls;
|
||||
static std::map<uint64_t, Base*> ResultHandlers;
|
||||
static std::vector<Result> Results;
|
||||
static std::vector<Base*> CallbackList;
|
||||
static std::recursive_mutex Mutex;
|
||||
};
|
||||
|
||||
STEAM_EXPORT bool SteamAPI_Init();
|
||||
|
@ -47,4 +47,10 @@ namespace Utils
|
||||
return Utils::WebIO(useragent, Cache::GetUrl(Cache::ValidUrl, path)).setTimeout(timeout)->get();
|
||||
}
|
||||
}
|
||||
|
||||
void Cache::Uninitialize()
|
||||
{
|
||||
std::lock_guard<std::mutex> _(Cache::CacheMutex);
|
||||
Cache::ValidUrl.clear();
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ namespace Utils
|
||||
public:
|
||||
static std::string GetStaticUrl(std::string path);
|
||||
static std::string GetFile(std::string path, int timeout = 5000, std::string useragent = "IW4x");
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
static std::mutex CacheMutex;
|
||||
|
Loading…
Reference in New Issue
Block a user