mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Core: fix several initialization bugs
- Don't free console if the process is being closed from the console, this will cause the process to freeze within the FreeConsole() call - Properly check for CPU features in order, and moved all checks to a single function utilizing the CPUInformation struct. - Made SDK_Init() and SDK_Shutdown() more resilient against mistakes with new checks and error messages (added since they are exported now).
This commit is contained in:
parent
b4ad19275f
commit
bf5dd318a7
@ -3,6 +3,7 @@
|
||||
#include "core/init.h"
|
||||
#include "core/logdef.h"
|
||||
#include "core/logger.h"
|
||||
#include "tier0/cpu.h"
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/crashhandler.h"
|
||||
#include "tier0/commandline.h"
|
||||
@ -24,6 +25,11 @@
|
||||
#endif
|
||||
|
||||
bool g_bSdkInitialized = false;
|
||||
|
||||
bool g_bSdkInitCallInitiated = false;
|
||||
bool g_bSdkShutdownCallInitiated = false;
|
||||
|
||||
bool g_bSdkShutdownInitiatedFromConsoleHandler = false;
|
||||
HMODULE s_hModuleHandle = NULL;
|
||||
|
||||
//#############################################################################
|
||||
@ -77,7 +83,21 @@ void Tier0_Init()
|
||||
|
||||
void SDK_Init()
|
||||
{
|
||||
CheckCPU(); // Check CPU as early as possible; error out if CPU isn't supported.
|
||||
assert(!g_bSdkInitialized);
|
||||
|
||||
CheckSystemCPU(); // Check CPU as early as possible; error out if CPU isn't supported.
|
||||
|
||||
if (g_bSdkInitCallInitiated)
|
||||
{
|
||||
spdlog::error("Recursive initialization!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set after checking cpu and initializing MathLib since we check CPU
|
||||
// features there. Else we crash on the recursive initialization error as
|
||||
// SpdLog uses SSE features.
|
||||
g_bSdkInitCallInitiated = true;
|
||||
|
||||
MathLib_Init(); // Initialize Mathlib.
|
||||
|
||||
PEB64* pEnv = CModule::GetProcessEnvironmentBlock();
|
||||
@ -129,13 +149,25 @@ void SDK_Shutdown()
|
||||
{
|
||||
assert(g_bSdkInitialized);
|
||||
|
||||
if (!g_bSdkInitialized)
|
||||
// Also check CPU in shutdown, since this function is exported, if they
|
||||
// call this with an unsupported CPU we should let them know rather than
|
||||
// crashing the process.
|
||||
CheckSystemCPU();
|
||||
|
||||
if (g_bSdkShutdownCallInitiated)
|
||||
{
|
||||
spdlog::error("Recursive shutdown!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
g_bSdkInitialized = false;
|
||||
g_bSdkShutdownCallInitiated = true;
|
||||
|
||||
if (!g_bSdkInitialized)
|
||||
{
|
||||
spdlog::error("Not initialized!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Msg(eDLL_T::NONE, "GameSDK shutdown initiated\n");
|
||||
|
||||
curl_global_cleanup();
|
||||
@ -151,7 +183,13 @@ void SDK_Shutdown()
|
||||
Winsock_Shutdown();
|
||||
|
||||
SpdLog_Shutdown();
|
||||
Console_Shutdown();
|
||||
|
||||
// If the shutdown was initiated from the console window itself, don't
|
||||
// shutdown the console as it would otherwise deadlock in FreeConsole!
|
||||
if (!g_bSdkShutdownInitiatedFromConsoleHandler)
|
||||
Console_Shutdown();
|
||||
|
||||
g_bSdkInitialized = false;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
|
@ -418,33 +418,6 @@ void QuerySystemInfo()
|
||||
}
|
||||
}
|
||||
|
||||
void CheckCPU() // Respawn's engine and our SDK utilize POPCNT, SSE3 and SSSE3 (Supplemental SSE 3 Instructions).
|
||||
{
|
||||
CpuIdResult_t cpuResult;
|
||||
__cpuid(reinterpret_cast<int*>(&cpuResult), 1);
|
||||
|
||||
char szBuf[1024];
|
||||
|
||||
if ((cpuResult.ecx & (1 << 0)) == 0)
|
||||
{
|
||||
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "SSE 3");
|
||||
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
|
||||
ExitProcess(0xFFFFFFFF);
|
||||
}
|
||||
if ((cpuResult.ecx & (1 << 9)) == 0)
|
||||
{
|
||||
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "SSSE 3 (Supplemental SSE 3 Instructions)");
|
||||
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
|
||||
ExitProcess(0xFFFFFFFF);
|
||||
}
|
||||
if ((cpuResult.ecx & (1 << 23)) == 0)
|
||||
{
|
||||
V_snprintf(szBuf, sizeof(szBuf), "CPU does not have %s!\n", "POPCNT");
|
||||
MessageBoxA(NULL, szBuf, "Unsupported CPU", MB_ICONERROR | MB_OK);
|
||||
ExitProcess(0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (DEDICATED)
|
||||
#define SIGDB_FILE "cfg/server/startup.bin"
|
||||
#elif defined (CLIENT_DLL)
|
||||
|
@ -11,10 +11,10 @@ void Winsock_Shutdown();
|
||||
void DirtySDK_Startup();
|
||||
void DirtySDK_Shutdown();
|
||||
void QuerySystemInfo();
|
||||
void CheckCPU();
|
||||
|
||||
void DetourInit();
|
||||
void DetourAddress();
|
||||
void DetourRegister();
|
||||
|
||||
extern bool g_bSdkInitialized;
|
||||
extern bool g_bSdkShutdownInitiatedFromConsoleHandler;
|
||||
|
@ -4059,11 +4059,6 @@ void MathLib_Init(float gamma, float texGamma, float brightness, int overbright)
|
||||
|
||||
// FIXME: Hook SSE into VectorAligned + Vector4DAligned
|
||||
|
||||
#if !defined( _GAMECONSOLE )
|
||||
CheckCPUforSSE2();
|
||||
#endif //!360
|
||||
|
||||
|
||||
s_bMathlibInitialized = true;
|
||||
|
||||
InitSinCosTable();
|
||||
|
@ -470,7 +470,9 @@ const CPUInformation& GetCPUInformation(void)
|
||||
pi.m_bSSE41 = (cpuid1.ecx >> 19) & 1;
|
||||
pi.m_bSSE42 = (cpuid1.ecx >> 20) & 1;
|
||||
pi.m_b3DNow = Check3DNowTechnology();
|
||||
pi.m_bPOPCNT= (cpuid1.ecx >> 23) & 1;
|
||||
pi.m_bAVX = (cpuid1.ecx >> 28) & 1;
|
||||
pi.m_bHRVSR = (cpuid1.ecx >> 31) & 1;
|
||||
pi.m_szProcessorID = const_cast<char*>(GetProcessorVendorId());
|
||||
pi.m_szProcessorBrand = const_cast<char*>(GetProcessorBrand());
|
||||
pi.m_bHT = (pi.m_nPhysicalProcessors < pi.m_nLogicalProcessors); //HTSupported();
|
||||
@ -573,16 +575,36 @@ const CPUInformation& GetCPUInformation(void)
|
||||
return pi;
|
||||
}
|
||||
|
||||
void CheckCPUforSSE2()
|
||||
void CheckSystemCPU()
|
||||
{
|
||||
const CPUInformation& pi = GetCPUInformation();
|
||||
|
||||
if (!(pi.m_bSSE && pi.m_bSSE2))
|
||||
{
|
||||
Assert(0);
|
||||
if (MessageBoxA(NULL, "SSE and SSE2 are required.", "Unsupported CPU", MB_ICONERROR | MB_OK))
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), EXIT_FAILURE);
|
||||
TerminateProcess(GetCurrentProcess(), 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
if (!pi.m_bSSE3)
|
||||
{
|
||||
if (MessageBoxA(NULL, "SSE3 is required.", "Unsupported CPU", MB_ICONERROR | MB_OK))
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
if (!pi.m_bSSSE3)
|
||||
{
|
||||
if (MessageBoxA(NULL, "SSSE3 (Supplemental SSE3 Instructions) is required.", "Unsupported CPU", MB_ICONERROR | MB_OK))
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
if (!pi.m_bPOPCNT)
|
||||
{
|
||||
if (MessageBoxA(NULL, "POPCNT is required.", "Unsupported CPU", MB_ICONERROR | MB_OK))
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,9 @@ struct CPUInformation
|
||||
m_bSSE4a : 1,
|
||||
m_bSSE41 : 1,
|
||||
m_bSSE42 : 1,
|
||||
m_bAVX : 1; // Is AVX supported?
|
||||
m_bPOPCNT: 1, // Pop count
|
||||
m_bAVX : 1, // Advanced Vector Extensions
|
||||
m_bHRVSR : 1; // Hypervisor
|
||||
|
||||
uint32 m_nModel;
|
||||
uint32 m_nFeatures[3];
|
||||
@ -94,12 +96,14 @@ struct CPUInformation
|
||||
m_szProcessorID = nullptr;
|
||||
m_szProcessorBrand = nullptr;
|
||||
|
||||
m_bSSE3 = false;
|
||||
m_bSSSE3 = false;
|
||||
m_bSSE4a = false;
|
||||
m_bSSE41 = false;
|
||||
m_bSSE42 = false;
|
||||
m_bAVX = false;
|
||||
m_bSSE3 = false;
|
||||
m_bSSSE3 = false;
|
||||
m_bSSE4a = false;
|
||||
m_bSSE41 = false;
|
||||
m_bSSE42 = false;
|
||||
m_bPOPCNT = false;
|
||||
m_bAVX = false;
|
||||
m_bHRVSR = false;
|
||||
|
||||
m_nModel = 0;
|
||||
m_nFeatures[0] = 0;
|
||||
@ -126,6 +130,6 @@ const char* GetProcessorBrand(bool bRemovePadding);
|
||||
|
||||
const CPUInformation& GetCPUInformation(void);
|
||||
|
||||
void CheckCPUforSSE2();
|
||||
void CheckSystemCPU();
|
||||
|
||||
#endif // CPU_H
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "core/init.h"
|
||||
#include "windows/system.h"
|
||||
#include "engine/host_state.h"
|
||||
|
||||
@ -61,14 +62,18 @@ ConsoleHandlerRoutine(
|
||||
case CTRL_CLOSE_EVENT:
|
||||
case CTRL_LOGOFF_EVENT:
|
||||
case CTRL_SHUTDOWN_EVENT:
|
||||
if (g_pHostState)
|
||||
{
|
||||
g_pHostState->m_iNextState = HostStates_t::HS_SHUTDOWN;
|
||||
}
|
||||
|
||||
if (!g_bSdkShutdownInitiatedFromConsoleHandler)
|
||||
g_bSdkShutdownInitiatedFromConsoleHandler = true;
|
||||
|
||||
// Give it time to shutdown properly, value is set to the max possible
|
||||
if (g_pHostState) // This tells the engine to gracefully shutdown on the next frame.
|
||||
g_pHostState->m_iNextState = HostStates_t::HS_SHUTDOWN;
|
||||
|
||||
// Give it time to shutdown properly, this loop waits for max time
|
||||
// of SPI_GETWAITTOKILLSERVICETIMEOUT, which is 20000ms by default.
|
||||
Sleep(20000);
|
||||
while (g_bSdkInitialized)
|
||||
Sleep(50);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user