Core/Maps: Unload transports in MapManager::UnloadAll instead of singleton destructor.
Core/Transports: Properly delink units from transports on transport desutruction. - Thanks to Shauren for help. Core/ObjectAccessor: Unload corpse 'storage' in added UnloadAll method called in WorldRunnable postservice hook. Core/Master: Change some postservice queries to syncrhonous (direct) execution to ensure execution on shutdown Core/Master: Remove redundant calls to ACE::init and ACE::fini These changes were made to fix crash/freeze issues on shutdown.
This commit is contained in:
@@ -180,8 +180,11 @@ Transport::Transport(uint32 period, uint32 script) : GameObject(), m_period(peri
|
|||||||
|
|
||||||
Transport::~Transport()
|
Transport::~Transport()
|
||||||
{
|
{
|
||||||
for (CreatureSet::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end();)
|
for (CreatureSet::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end(); ++itr)
|
||||||
(*(itr++))->ForcedDespawn();
|
{
|
||||||
|
(*itr)->SetTransport(NULL);
|
||||||
|
GetMap()->AddObjectToRemoveList(*itr);
|
||||||
|
}
|
||||||
|
|
||||||
m_NPCPassengerSet.clear();
|
m_NPCPassengerSet.clear();
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,6 @@ ObjectAccessor::ObjectAccessor()
|
|||||||
|
|
||||||
ObjectAccessor::~ObjectAccessor()
|
ObjectAccessor::~ObjectAccessor()
|
||||||
{
|
{
|
||||||
for (Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr)
|
|
||||||
{
|
|
||||||
itr->second->RemoveFromWorld();
|
|
||||||
delete itr->second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid)
|
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid)
|
||||||
@@ -385,6 +380,15 @@ void ObjectAccessor::Update(uint32 /*diff*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectAccessor::UnloadAll()
|
||||||
|
{
|
||||||
|
for (Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr)
|
||||||
|
{
|
||||||
|
itr->second->RemoveFromWorld();
|
||||||
|
delete itr->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Define the static members of HashMapHolder
|
/// Define the static members of HashMapHolder
|
||||||
|
|
||||||
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
|
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ class DynamicObject;
|
|||||||
class WorldObject;
|
class WorldObject;
|
||||||
class Vehicle;
|
class Vehicle;
|
||||||
class Map;
|
class Map;
|
||||||
|
class WorldRunnable;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class HashMapHolder
|
class HashMapHolder
|
||||||
@@ -84,6 +85,7 @@ class HashMapHolder
|
|||||||
class ObjectAccessor
|
class ObjectAccessor
|
||||||
{
|
{
|
||||||
friend class ACE_Singleton<ObjectAccessor, ACE_Thread_Mutex>;
|
friend class ACE_Singleton<ObjectAccessor, ACE_Thread_Mutex>;
|
||||||
|
friend class WorldRunnable;
|
||||||
ObjectAccessor();
|
ObjectAccessor();
|
||||||
~ObjectAccessor();
|
~ObjectAccessor();
|
||||||
ObjectAccessor(const ObjectAccessor&);
|
ObjectAccessor(const ObjectAccessor&);
|
||||||
@@ -254,6 +256,9 @@ class ObjectAccessor
|
|||||||
|
|
||||||
typedef ACE_Thread_Mutex LockType;
|
typedef ACE_Thread_Mutex LockType;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void UnloadAll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Player2CorpsesMapType i_player2corpse;
|
Player2CorpsesMapType i_player2corpse;
|
||||||
|
|||||||
@@ -45,16 +45,6 @@ MapManager::MapManager()
|
|||||||
|
|
||||||
MapManager::~MapManager()
|
MapManager::~MapManager()
|
||||||
{
|
{
|
||||||
for (MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
|
|
||||||
delete iter->second;
|
|
||||||
|
|
||||||
for (TransportSet::iterator i = m_Transports.begin(); i != m_Transports.end(); ++i)
|
|
||||||
{
|
|
||||||
(*i)->RemoveFromWorld();
|
|
||||||
delete *i;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map::DeleteStateMachine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapManager::Initialize()
|
void MapManager::Initialize()
|
||||||
@@ -305,17 +295,23 @@ bool MapManager::IsValidMAP(uint32 mapid)
|
|||||||
|
|
||||||
void MapManager::UnloadAll()
|
void MapManager::UnloadAll()
|
||||||
{
|
{
|
||||||
for (MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
|
for (TransportSet::iterator i = m_Transports.begin(); i != m_Transports.end(); ++i)
|
||||||
iter->second->UnloadAll();
|
|
||||||
|
|
||||||
while (!i_maps.empty())
|
|
||||||
{
|
{
|
||||||
delete i_maps.begin()->second;
|
(*i)->RemoveFromWorld();
|
||||||
i_maps.erase(i_maps.begin());
|
delete *i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MapMapType::iterator iter = i_maps.begin(); iter != i_maps.end();)
|
||||||
|
{
|
||||||
|
iter->second->UnloadAll();
|
||||||
|
delete iter->second;
|
||||||
|
i_maps.erase(iter++);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_updater.activated())
|
if (m_updater.activated())
|
||||||
m_updater.deactivate();
|
m_updater.deactivate();
|
||||||
|
|
||||||
|
Map::DeleteStateMachine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapManager::InitMaxInstanceId()
|
void MapManager::InitMaxInstanceId()
|
||||||
|
|||||||
@@ -72,8 +72,6 @@ void usage(const char *prog)
|
|||||||
/// Launch the Trinity server
|
/// Launch the Trinity server
|
||||||
extern int main(int argc, char **argv)
|
extern int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
ACE::init();
|
|
||||||
|
|
||||||
///- Command line parsing to get the configuration file name
|
///- Command line parsing to get the configuration file name
|
||||||
char const* cfg_file = _TRINITY_CORE_CONFIG;
|
char const* cfg_file = _TRINITY_CORE_CONFIG;
|
||||||
int c=1;
|
int c=1;
|
||||||
@@ -151,8 +149,6 @@ extern int main(int argc, char **argv)
|
|||||||
// 1 - shutdown at error
|
// 1 - shutdown at error
|
||||||
// 2 - restart command used, this code can be used by restarter for restart Trinityd
|
// 2 - restart command used, this code can be used by restarter for restart Trinityd
|
||||||
|
|
||||||
ACE::fini();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ int Master::Run()
|
|||||||
CoredSignalHandler SignalBREAK;
|
CoredSignalHandler SignalBREAK;
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
// Register realmd's signal handlers
|
// Register core's signal handlers
|
||||||
ACE_Sig_Handler Handler;
|
ACE_Sig_Handler Handler;
|
||||||
Handler.register_handler(SIGINT, &SignalINT);
|
Handler.register_handler(SIGINT, &SignalINT);
|
||||||
Handler.register_handler(SIGTERM, &SignalTERM);
|
Handler.register_handler(SIGTERM, &SignalTERM);
|
||||||
@@ -290,7 +290,7 @@ int Master::Run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set server offline
|
// set server offline
|
||||||
LoginDatabase.PExecute("UPDATE realmlist SET color = color | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);
|
LoginDatabase.DirectPExecute("UPDATE realmlist SET color = color | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID);
|
||||||
|
|
||||||
// when the main thread closes the singletons get unloaded
|
// when the main thread closes the singletons get unloaded
|
||||||
// since worldrunnable uses them, it will crash if unloaded after master
|
// since worldrunnable uses them, it will crash if unloaded after master
|
||||||
@@ -484,12 +484,12 @@ void Master::clearOnlineAccounts()
|
|||||||
{
|
{
|
||||||
// Cleanup online status for characters hosted at current realm
|
// Cleanup online status for characters hosted at current realm
|
||||||
/// \todo Only accounts with characters logged on *this* realm should have online status reset. Move the online column from 'account' to 'realmcharacters'?
|
/// \todo Only accounts with characters logged on *this* realm should have online status reset. Move the online column from 'account' to 'realmcharacters'?
|
||||||
LoginDatabase.PExecute(
|
LoginDatabase.DirectPExecute(
|
||||||
"UPDATE account SET online = 0 WHERE online > 0 "
|
"UPDATE account SET online = 0 WHERE online > 0 "
|
||||||
"AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID);
|
"AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID);
|
||||||
|
|
||||||
CharacterDatabase.Execute("UPDATE characters SET online = 0 WHERE online<>0");
|
CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online<>0");
|
||||||
|
|
||||||
// Battleground instance ids reset at server restart
|
// Battleground instance ids reset at server restart
|
||||||
CharacterDatabase.Execute("UPDATE character_battleground_data SET instance_id = 0");
|
CharacterDatabase.DirectExecute("UPDATE character_battleground_data SET instance_id = 0");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,6 @@ void WorldRunnable::run()
|
|||||||
|
|
||||||
sWorldSocketMgr->StopNetwork();
|
sWorldSocketMgr->StopNetwork();
|
||||||
|
|
||||||
|
sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world
|
||||||
sMapMgr->UnloadAll(); // unload all grids (including locked in memory)
|
sMapMgr->UnloadAll(); // unload all grids (including locked in memory)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user