[General] Fix protobuf and other memory leaks

This commit is contained in:
momo5502 2017-01-22 20:12:36 +01:00
parent f81a36ae3b
commit 2de95b4a3b
13 changed files with 119 additions and 55 deletions

View File

@ -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;
}
}

View File

@ -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;
};
}

View File

@ -250,6 +250,7 @@ namespace Components
delwin(Console::InputWindow);
delwin(Console::InfoWindow);
endwin();
delscreen(SP);
Console::OutputWindow = nullptr;
Console::InputWindow = nullptr;

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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));
}
}
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -42,6 +42,8 @@ namespace Main
void Uninitialize()
{
Components::Loader::Uninitialize();
Utils::Cache::Uninitialize();
google::protobuf::ShutdownProtobufLibrary();
}
}

View File

@ -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()

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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;