Fix various memory leaks with RAII

This commit is contained in:
Lion Kortlepel
2020-11-04 13:10:45 +01:00
parent 5452aeb558
commit f2d87078ae
4 changed files with 512 additions and 408 deletions

View File

@@ -3,66 +3,76 @@
/// ///
#pragma once #pragma once
#include "lua.hpp"
#include <any>
#include <filesystem> #include <filesystem>
#include <iostream> #include <iostream>
#include "lua.hpp"
#include <vector>
#include <thread>
#include <mutex> #include <mutex>
#include <memory>
#include <set> #include <set>
#include <any> #include <thread>
#include <vector>
namespace fs = std::filesystem; namespace fs = std::filesystem;
struct LuaArg{ struct LuaArg {
std::vector<std::any> args; std::vector<std::any> args;
void PushArgs(lua_State *State){ void PushArgs(lua_State* State) {
for(std::any arg : args){ for (std::any arg : args) {
if(!arg.has_value())return; if (!arg.has_value())
return;
std::string Type = arg.type().name(); std::string Type = arg.type().name();
if(Type.find("bool") != std::string::npos){ if (Type.find("bool") != std::string::npos) {
lua_pushboolean(State,std::any_cast<bool>(arg)); lua_pushboolean(State, std::any_cast<bool>(arg));
} }
if(Type.find("basic_string") != std::string::npos || Type.find("char") != std::string::npos){ if (Type.find("basic_string") != std::string::npos || Type.find("char") != std::string::npos) {
lua_pushstring(State,std::any_cast<std::string>(arg).c_str()); lua_pushstring(State, std::any_cast<std::string>(arg).c_str());
} }
if(Type.find("int") != std::string::npos){ if (Type.find("int") != std::string::npos) {
lua_pushinteger(State,std::any_cast<int>(arg)); lua_pushinteger(State, std::any_cast<int>(arg));
} }
if(Type.find("float") != std::string::npos){ lua_pushnumber(State,std::any_cast<float>(arg)); if (Type.find("float") != std::string::npos) {
lua_pushnumber(State, std::any_cast<float>(arg));
} }
} }
} }
}; };
class Lua { class Lua {
private: private:
std::set<std::pair<std::string,std::string>> RegisteredEvents; std::set<std::pair<std::string, std::string>> _RegisteredEvents;
lua_State *luaState = luaL_newstate(); lua_State* luaState { nullptr };
fs::file_time_type LastWrote; fs::file_time_type _LastWrote;
std::string PluginName; std::string _PluginName;
std::string FileName; std::string _FileName;
bool _StopThread = false;
bool _Console = false;
// this is called by the ctor to ensure RAII
void Init();
public: public:
void RegisterEvent(const std::string&Event,const std::string&FunctionName); void RegisterEvent(const std::string& Event, const std::string& FunctionName);
std::string GetRegistered(const std::string&Event); std::string GetRegistered(const std::string& Event) const;
void UnRegisterEvent(const std::string&Event); void UnRegisterEvent(const std::string& Event);
void SetLastWrite(fs::file_time_type time); void SetLastWrite(fs::file_time_type time);
bool IsRegistered(const std::string&Event); bool IsRegistered(const std::string& Event);
void SetPluginName(const std::string&Name); void SetPluginName(const std::string& Name);
void Execute(const std::string& Command); void Execute(const std::string& Command);
void SetFileName(const std::string&Name); void SetFileName(const std::string& Name);
fs::file_time_type GetLastWrite(); fs::file_time_type GetLastWrite();
std::string GetPluginName(); std::string GetPluginName() const;
std::string GetFileName(); std::string GetFileName() const;
bool StopThread = false;
bool Console = false;
lua_State* GetState(); lua_State* GetState();
const lua_State* GetState() const;
char* GetOrigin(); char* GetOrigin();
std::mutex Lock; std::mutex Lock;
void Reload(); void Reload();
void Init(); Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false);
Lua(bool Console = false);
~Lua();
void SetStopThread(bool StopThread) { _StopThread = StopThread; }
bool GetStopThread() const { return _StopThread; }
}; };
int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* args); int CallFunction(Lua* lua, const std::string& FuncName, LuaArg* args);
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg,bool Wait); int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, LuaArg* arg, bool Wait);
extern std::set<Lua*> PluginEngine; extern std::set<std::unique_ptr<Lua>> PluginEngine;

View File

@@ -130,9 +130,7 @@ void SetupConsole() {
} }
void ConsoleInit() { void ConsoleInit() {
SetupConsole(); SetupConsole();
LuaConsole = new Lua(); LuaConsole = new Lua(true);
LuaConsole->Console = true;
LuaConsole->Init();
printf("> "); printf("> ");
std::thread In(ReadCin); std::thread In(ReadCin);
In.detach(); In.detach();

View File

@@ -2,10 +2,10 @@
/// Created by Anonymous275 on 5/20/2020 /// Created by Anonymous275 on 5/20/2020
/// ///
#include "Logger.h"
#include "Lua/LuaSystem.hpp" #include "Lua/LuaSystem.hpp"
#include "Security/Enc.h" #include "Security/Enc.h"
#include "Settings.h" #include "Settings.h"
#include "Logger.h"
#include <thread> #include <thread>
#ifdef __linux #ifdef __linux
@@ -13,75 +13,73 @@
#include <sys/stat.h> #include <sys/stat.h>
#endif // __linux #endif // __linux
std::set<Lua*> PluginEngine; std::set<std::unique_ptr<Lua>> PluginEngine;
bool NewFile(const std::string&Path){ bool NewFile(const std::string& Path) {
for(Lua*Script : PluginEngine){ for (auto& Script : PluginEngine) {
if(Path == Script->GetFileName())return false; if (Path == Script->GetFileName())
return false;
} }
return true; return true;
} }
void RegisterFiles(const std::string& Path,bool HotSwap){ void RegisterFiles(const std::string& Path, bool HotSwap) {
std::string Name = Path.substr(Path.find_last_of('\\')+1); std::string Name = Path.substr(Path.find_last_of('\\') + 1);
if(!HotSwap)info(Sec("Loading plugin : ") + Name); if (!HotSwap)
for (const auto &entry : fs::directory_iterator(Path)){ info(Sec("Loading plugin : ") + Name);
for (const auto& entry : fs::directory_iterator(Path)) {
auto pos = entry.path().string().find(Sec(".lua")); auto pos = entry.path().string().find(Sec(".lua"));
if (pos != std::string::npos && entry.path().string().length() - pos == 4) { if (pos != std::string::npos && entry.path().string().length() - pos == 4) {
if(!HotSwap || NewFile(entry.path().string())){ if (!HotSwap || NewFile(entry.path().string())) {
Lua *Script = new Lua(); auto FileName = entry.path().string();
PluginEngine.insert(Script); std::unique_ptr<Lua> ScriptToInsert(new Lua(Name, FileName, fs::last_write_time(FileName)));
Script->SetFileName(entry.path().string()); auto& Script = *ScriptToInsert;
Script->SetPluginName(Name); PluginEngine.insert(std::move(ScriptToInsert));
Script->SetLastWrite(fs::last_write_time(Script->GetFileName())); if (HotSwap)
Script->Init(); info(Sec("[HOTSWAP] Added : ") + Script.GetFileName().substr(Script.GetFileName().find('\\')));
if(HotSwap)info(Sec("[HOTSWAP] Added : ") +
Script->GetFileName().substr(Script->GetFileName().find('\\')));
} }
} }
} }
} }
void FolderList(const std::string& Path,bool HotSwap){ void FolderList(const std::string& Path, bool HotSwap) {
for (const auto &entry : fs::directory_iterator(Path)) { for (const auto& entry : fs::directory_iterator(Path)) {
auto pos = entry.path().filename().string().find('.'); auto pos = entry.path().filename().string().find('.');
if (pos == std::string::npos) { if (pos == std::string::npos) {
RegisterFiles(entry.path().string(),HotSwap); RegisterFiles(entry.path().string(), HotSwap);
} }
} }
} }
[[noreturn]]void HotSwaps(const std::string& path){ [[noreturn]] void HotSwaps(const std::string& path) {
DebugPrintTID(); DebugPrintTID();
while(true){ while (true) {
for(Lua*Script : PluginEngine){ for (auto& Script : PluginEngine) {
struct stat Info{}; struct stat Info {};
if(stat(Script->GetFileName().c_str(), &Info) != 0){ if (stat(Script->GetFileName().c_str(), &Info) != 0) {
Script->StopThread = true; Script->SetStopThread(true);
PluginEngine.erase(Script); PluginEngine.erase(Script);
info(Sec("[HOTSWAP] Removed : ")+ info(Sec("[HOTSWAP] Removed : ") + Script->GetFileName().substr(Script->GetFileName().find('\\')));
Script->GetFileName().substr(Script->GetFileName().find('\\')));
break; break;
} }
if(Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())){ if (Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())) {
Script->StopThread = true; Script->SetStopThread(true);
info(Sec("[HOTSWAP] Updated : ")+ info(Sec("[HOTSWAP] Updated : ") + Script->GetFileName().substr(Script->GetFileName().find('\\')));
Script->GetFileName().substr(Script->GetFileName().find('\\')));
Script->SetLastWrite(fs::last_write_time(Script->GetFileName())); Script->SetLastWrite(fs::last_write_time(Script->GetFileName()));
Script->Reload(); Script->Reload();
} }
} }
FolderList(path,true); FolderList(path, true);
std::this_thread::sleep_for(std::chrono::seconds(2)); std::this_thread::sleep_for(std::chrono::seconds(2));
} }
} }
void InitLua(){ void InitLua() {
if(!fs::exists(Resource)){ if (!fs::exists(Resource)) {
fs::create_directory(Resource); fs::create_directory(Resource);
} }
std::string Path = Resource + Sec("/Server"); std::string Path = Resource + Sec("/Server");
if(!fs::exists(Path)){ if (!fs::exists(Path)) {
fs::create_directory(Path); fs::create_directory(Path);
} }
FolderList(Path,false); FolderList(Path, false);
std::thread t1(HotSwaps,Path); std::thread t1(HotSwaps, Path);
t1.detach(); t1.detach();
info(Sec("Lua system online")); info(Sec("Lua system online"));
} }

File diff suppressed because it is too large Load Diff