1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2025-03-21 12:28:56 +01:00

Now unloading the original gamedll in DLLShutdown() instead of using a __attribute__((destructor)) function

-> Also auto-removing ConCommandBases with the FCVAR_GAMEDLL flag before doing that

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40115
This commit is contained in:
Pavol Marko 2005-09-24 21:10:53 +00:00
parent e242aa662d
commit 18bfaa7021
3 changed files with 41 additions and 33 deletions

View File

@ -84,6 +84,37 @@ void SMConVarAccessor::Unregister(ConCommandBase *pCommand)
}
}
void SMConVarAccessor::UnregisterGameDLLCommands()
{
ConCommandBase *begin = g_Engine.icvar->GetCommands();
ConCommandBase *iter = begin;
ConCommandBase *prev = NULL;
while (iter)
{
// watch out for the ETERNAL COMMAND!
if (iter != &g_EternalCommand && iter->IsBitSet(FCVAR_GAMEDLL))
{
// Remove it!
if (iter == begin)
{
g_EternalCommand.BringToFront();
iter = const_cast<ConCommandBase*>(iter->GetNext());
g_EternalCommand.SetNext(iter);
prev = &g_EternalCommand;
continue;
}
else
{
iter = const_cast<ConCommandBase*>(iter->GetNext());
prev->SetNext(iter);
continue;
}
}
prev = iter;
iter = const_cast<ConCommandBase*>(iter->GetNext());
}
}
ConVar metamod_version("metamod_version", SOURCEMM_VERSION, FCVAR_REPLICATED | FCVAR_SPONLY | FCVAR_NOTIFY, "Metamod:Source Version");
#if defined WIN32 || defined _WIN32
ConVar mm_pluginsfile("mm_pluginsfile", "addons\\metamod\\metaplugins.ini", FCVAR_SPONLY, "Metamod:Source Plugins File");

View File

@ -30,6 +30,7 @@ public:
bool Register(ConCommandBase *pCommand);
void MarkCommandsAsGameDLL();
void Unregister(ConCommandBase *pCommand);
void UnregisterGameDLLCommands();
};
class CAlwaysRegisterableCommand : public ConCommandBase

View File

@ -37,7 +37,6 @@ SourceHook::ISourceHook *g_SHPtr;
SourceHook::String g_ModPath;
SourceHook::String g_BinPath;
PluginId g_PLID = Pl_Console; //Technically, SourceMM is the "Console" plugin... :p
bool bInShutdown = false;
bool bInFirstLevel = true;
///////////////////////////////////
@ -268,44 +267,21 @@ void Shutdown()
g_SMConVarAccessor.MarkCommandsAsGameDLL();
}
// The engine uses the DLL even after it has call DLLShutdown, so we unload it
// when it unloads us
#if defined _WIN32
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
if (fdwReason == DLL_PROCESS_DETACH)
{
if (!bInShutdown)
Shutdown();
if (g_GameDll.lib && g_GameDll.loaded)
dlclose(g_GameDll.lib);
memset(&g_GameDll, 0, sizeof(GameDllInfo));
}
return TRUE;
}
#elif defined __linux__
void __attribute__ ((destructor)) app_fini(void)
{
if (!bInShutdown)
Shutdown();
if (g_GameDll.lib && g_GameDll.loaded)
dlclose(g_GameDll.lib);
memset(&g_GameDll, 0, sizeof(GameDllInfo));
}
#endif
void CServerGameDLL::DLLShutdown()
{
Shutdown();
//Call the original function
//Call the original function
m_pOrig->DLLShutdown();
bInShutdown = true;
//Unregister all commands marked as GameDLL now
//This prevents crashes when the engine tries to unregister them once we have already unloaded the gamedll
//(we used to unload the gamedll in a __attribute__((destructor)) function but I've had problems with that (crashes in dlclose)
g_SMConVarAccessor.UnregisterGameDLLCommands();
if (g_GameDll.lib && g_GameDll.loaded)
dlclose(g_GameDll.lib);
memset(&g_GameDll, 0, sizeof(GameDllInfo));
}
int LoadPluginsFromFile(const char *file)