1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +01:00

Fix the crash at shut down caused by forgetting to release the global events table object.

Include the fixes from the routines that should've been commited into the previous commit.
Take a more exception safe approach to unbinding from server events at shutdown.
This commit is contained in:
Sandu Liviu Catalin 2017-02-21 21:42:40 +02:00
parent 41e04e5167
commit e7bb68d76c
4 changed files with 59 additions and 47 deletions

View File

@ -308,6 +308,7 @@ void Core::DropEvents()
ResetSignalPair(mOnServerOption);
ResetSignalPair(mOnScriptReload);
ResetSignalPair(mOnScriptLoaded);
m_Events.Release();
}
} // Namespace:: SqMod

View File

@ -105,9 +105,65 @@ static uint8_t OnServerInitialise(void)
return ConvTo< Uint8 >::From(Core::Get().GetState());
}
/* ------------------------------------------------------------------------------------------------
* RAII approach to unbinding the server callbacks.
*/
struct CallbackUnbinder
{
~CallbackUnbinder()
{
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnServerFrame = nullptr;
_Clbk->OnPluginCommand = nullptr;
_Clbk->OnIncomingConnection = nullptr;
_Clbk->OnClientScriptData = nullptr;
_Clbk->OnPlayerConnect = nullptr;
_Clbk->OnPlayerDisconnect = nullptr;
_Clbk->OnPlayerRequestClass = nullptr;
_Clbk->OnPlayerRequestSpawn = nullptr;
_Clbk->OnPlayerSpawn = nullptr;
_Clbk->OnPlayerDeath = nullptr;
_Clbk->OnPlayerUpdate = nullptr;
_Clbk->OnPlayerRequestEnterVehicle = nullptr;
_Clbk->OnPlayerEnterVehicle = nullptr;
_Clbk->OnPlayerExitVehicle = nullptr;
_Clbk->OnPlayerNameChange = nullptr;
_Clbk->OnPlayerStateChange = nullptr;
_Clbk->OnPlayerActionChange = nullptr;
_Clbk->OnPlayerOnFireChange = nullptr;
_Clbk->OnPlayerCrouchChange = nullptr;
_Clbk->OnPlayerGameKeysChange = nullptr;
_Clbk->OnPlayerBeginTyping = nullptr;
_Clbk->OnPlayerEndTyping = nullptr;
_Clbk->OnPlayerAwayChange = nullptr;
_Clbk->OnPlayerMessage = nullptr;
_Clbk->OnPlayerCommand = nullptr;
_Clbk->OnPlayerPrivateMessage = nullptr;
_Clbk->OnPlayerKeyBindDown = nullptr;
_Clbk->OnPlayerKeyBindUp = nullptr;
_Clbk->OnPlayerSpectate = nullptr;
_Clbk->OnPlayerCrashReport = nullptr;
_Clbk->OnVehicleUpdate = nullptr;
_Clbk->OnVehicleExplode = nullptr;
_Clbk->OnVehicleRespawn = nullptr;
_Clbk->OnObjectShot = nullptr;
_Clbk->OnObjectTouched = nullptr;
_Clbk->OnPickupPickAttempt = nullptr;
_Clbk->OnPickupPicked = nullptr;
_Clbk->OnPickupRespawn = nullptr;
_Clbk->OnCheckpointEntered = nullptr;
_Clbk->OnCheckpointExited = nullptr;
_Clbk->OnEntityPoolChange = nullptr;
_Clbk->OnServerPerformanceReport = nullptr;
}
};
// ------------------------------------------------------------------------------------------------
static void OnServerShutdown(void)
{
// The server still triggers callbacks and we deallocated everything!
const CallbackUnbinder cu;
// Attempt to forward the event
try
{
@ -119,51 +175,6 @@ static void OnServerShutdown(void)
SQMOD_CATCH_EVENT_EXCEPTION(OnServerShutdown)
// See if a reload was requested (quite useless here but why not)
SQMOD_RELOAD_CHECK(g_Reload)
// The server still triggers callbacks and we deallocated everything!
_Clbk->OnServerInitialise = nullptr;
_Clbk->OnServerShutdown = nullptr;
_Clbk->OnServerFrame = nullptr;
_Clbk->OnPluginCommand = nullptr;
_Clbk->OnIncomingConnection = nullptr;
_Clbk->OnClientScriptData = nullptr;
_Clbk->OnPlayerConnect = nullptr;
_Clbk->OnPlayerDisconnect = nullptr;
_Clbk->OnPlayerRequestClass = nullptr;
_Clbk->OnPlayerRequestSpawn = nullptr;
_Clbk->OnPlayerSpawn = nullptr;
_Clbk->OnPlayerDeath = nullptr;
_Clbk->OnPlayerUpdate = nullptr;
_Clbk->OnPlayerRequestEnterVehicle = nullptr;
_Clbk->OnPlayerEnterVehicle = nullptr;
_Clbk->OnPlayerExitVehicle = nullptr;
_Clbk->OnPlayerNameChange = nullptr;
_Clbk->OnPlayerStateChange = nullptr;
_Clbk->OnPlayerActionChange = nullptr;
_Clbk->OnPlayerOnFireChange = nullptr;
_Clbk->OnPlayerCrouchChange = nullptr;
_Clbk->OnPlayerGameKeysChange = nullptr;
_Clbk->OnPlayerBeginTyping = nullptr;
_Clbk->OnPlayerEndTyping = nullptr;
_Clbk->OnPlayerAwayChange = nullptr;
_Clbk->OnPlayerMessage = nullptr;
_Clbk->OnPlayerCommand = nullptr;
_Clbk->OnPlayerPrivateMessage = nullptr;
_Clbk->OnPlayerKeyBindDown = nullptr;
_Clbk->OnPlayerKeyBindUp = nullptr;
_Clbk->OnPlayerSpectate = nullptr;
_Clbk->OnPlayerCrashReport = nullptr;
_Clbk->OnVehicleUpdate = nullptr;
_Clbk->OnVehicleExplode = nullptr;
_Clbk->OnVehicleRespawn = nullptr;
_Clbk->OnObjectShot = nullptr;
_Clbk->OnObjectTouched = nullptr;
_Clbk->OnPickupPickAttempt = nullptr;
_Clbk->OnPickupPicked = nullptr;
_Clbk->OnPickupRespawn = nullptr;
_Clbk->OnCheckpointEntered = nullptr;
_Clbk->OnCheckpointExited = nullptr;
_Clbk->OnEntityPoolChange = nullptr;
_Clbk->OnServerPerformanceReport = nullptr;
}
// ------------------------------------------------------------------------------------------------

View File

@ -39,7 +39,7 @@ void Routine::Process()
// Calculate the elapsed time
const Int32 delta = Int32((s_Last - s_Prev) / 1000L);
// Process all active routines
for (Interval * itr = s_Intervals; itr != (s_Intervals + SQMOD_MAX_TASKS); ++itr)
for (Interval * itr = s_Intervals; itr != (s_Intervals + SQMOD_MAX_ROUTINES); ++itr)
{
// Is this routine valid?
if (*itr)

View File

@ -292,7 +292,7 @@ public:
// Unable to find such routine
STHROWF("Unable to find a routine with tag (%s)", tag.mPtr);
// Should not reach this point but if it did, we have to return something
return s_Instances[SQMOD_MAX_TASKS].mInst; // Intentional Buffer overflow!
return s_Instances[SQMOD_MAX_ROUTINES].mInst; // Intentional Buffer overflow!
}
/* --------------------------------------------------------------------------------------------