diff --git a/CMakeLists.txt b/CMakeLists.txt index 86432ad7..3f6afb74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,7 @@ elseif(UNIX) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") # don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -g3") # funroll loops and everything else potentially crazy for performance here set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDEBUG_LEVEL=0 -DPRODUCTION=1 -Ofast -funroll-loops") @@ -80,7 +80,7 @@ elseif(UNIX) # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") #endif() - add_definitions(-DLINUX -D_REENTRANT -Dlinux -DSTELLA_INTERNAL -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500) + add_definitions(-DLINUX -D_REENTRANT -Dlinux -DSTELLA_INTERNAL -D_GNU_SOURCE -D_XOPEN_SOURCE=500) endif() add_subdirectory(external) diff --git a/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.cpp b/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.cpp index a6bb553f..9379508b 100755 --- a/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.cpp +++ b/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.cpp @@ -34,14 +34,14 @@ void ConfigServerDatabase::install(void) ConfigServerUtility::install(); data = &staticData; - KEY_INT (objvarNameCleanupTime, 0); - KEY_INT (orphanedObjectCleanupTime, 0); - KEY_INT (marketAttributesCleanupTime, 0); - KEY_INT (messagesCleanupTime, 0); - KEY_INT (brokenObjectCleanupTime, 0); - KEY_INT (vendorObjectCleanupTime, 0); + KEY_INT (objvarNameCleanupTime, 10); + KEY_INT (orphanedObjectCleanupTime, 10); + KEY_INT (marketAttributesCleanupTime, 10); + KEY_INT (messagesCleanupTime, 10); + KEY_INT (brokenObjectCleanupTime, 10); + KEY_INT (vendorObjectCleanupTime, 10); KEY_STRING (customSQLFilename,""); - KEY_BOOL (enableFixBadCells, false); + KEY_BOOL (enableFixBadCells, true); KEY_STRING (objectTemplateListUpdateFilename,""); KEY_STRING (DSN,"gameserver"); @@ -56,7 +56,7 @@ void ConfigServerDatabase::install(void) KEY_INT (taskManagerPort, 60001); KEY_INT (expectedDBVersion, 270); KEY_BOOL (correctDBVersionRequired,true); - KEY_INT (saveFrequencyLimit,10); + KEY_INT (saveFrequencyLimit,5); KEY_STRING (schemaOwner, ""); KEY_STRING (goldSchemaOwner, ""); KEY_FLOAT (uniqueMessageCacheTimeSec, 30.0f); @@ -72,10 +72,10 @@ void ConfigServerDatabase::install(void) KEY_BOOL (reportSaveTimes, false); KEY_BOOL (shouldSleep, true); KEY_BOOL (enableLoadLocks, true); - KEY_INT (databaseReconnectTime, 0); + KEY_INT (databaseReconnectTime, 1); KEY_BOOL (logChunkLoading,false); KEY_BOOL (useMemoryManagerForOCI,false); - KEY_INT (maxCharactersPerLoadRequest,10); + KEY_INT (maxCharactersPerLoadRequest,20); KEY_INT (maxChunksPerLoadRequest,200); KEY_FLOAT (maxLoadStartDelay,300.0f); KEY_INT (maxErrorCountBeforeDisconnect,5); @@ -106,11 +106,11 @@ void ConfigServerDatabase::install(void) KEY_INT (maxLoaderFinishedTasks, 100); KEY_FLOAT (reportLongFrameTime, 1.0f); KEY_BOOL (enableVerboseMessageLogging, false); - KEY_BOOL (profilerExpandAll, true); + KEY_BOOL (profilerExpandAll, false); KEY_INT (profilerDisplayPercentageMinimum, 0); KEY_BOOL (fatalOnDataError, false); KEY_INT (maxUnackedLoadCount, 1000000000); // by default, set to an "unlimited" number, and use maxUnackedLoadCountPerServer as the cap - KEY_INT (maxUnackedLoadCountPerServer, 2); + KEY_INT (maxUnackedLoadCountPerServer, 5); KEY_INT (auctionLocationLoadBatchSize, 100); KEY_INT (auctionLoadBatchSize, 100); KEY_INT (auctionAttributeLoadBatchSize, 100); diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp index f5dcb25c..5b097f2c 100755 --- a/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp +++ b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp @@ -91,13 +91,13 @@ m_queryFetchCount(0) centralServerConnection = new CentralServerConnection(ConfigServerDatabase::getCentralServerAddress(), ConfigServerDatabase::getCentralServerPort()); NetworkSetupData setup; - setup.maxConnections = 100; + setup.maxConnections = 300; setup.port = 0; setup.bindInterface = ConfigServerDatabase::getGameServiceBindInterface(); gameService = new Service(ConnectionAllocator(), setup); NetworkSetupData cmSetup; - cmSetup.maxConnections = 100; + cmSetup.maxConnections = 300; cmSetup.port = ConfigServerDatabase::getCommoditiesServerPort(); cmSetup.bindInterface = ConfigServerDatabase::getCommoditiesServerAddress(); commoditiesService = new Service(ConnectionAllocator(), cmSetup); @@ -128,7 +128,7 @@ m_queryFetchCount(0) DB::Server::setDisconnectSleepTime(ConfigServerDatabase::getDisconnectSleepTime()); DB::Server::setFatalOnDataError(ConfigServerDatabase::getFatalOnDataError()); - // the DatabaseProcess singleton will want to know when major, connection + // the DatabaseProcess singleton will want to know when major, connection // oriented events occur. These events are defined in Game, Task and Central // connection classes. connectToMessage("CentralConnectionOpened"); @@ -252,7 +252,7 @@ void DatabaseProcess::run(void) // TODO: sleep longer if idle if (shouldSleep) { - Os::sleep(1); + Os::sleep(3); } NetworkHandler::dispatch(); diff --git a/engine/server/library/serverDatabase/src/shared/Persister.cpp b/engine/server/library/serverDatabase/src/shared/Persister.cpp index 30f951c6..f4fd85b3 100755 --- a/engine/server/library/serverDatabase/src/shared/Persister.cpp +++ b/engine/server/library/serverDatabase/src/shared/Persister.cpp @@ -174,43 +174,32 @@ Persister::~Persister() { DEBUG_FATAL(taskQueue,("Call shutdown() before deleting Persister.\n")); - for (auto i = m_currentSnapshots.begin(); i!=m_currentSnapshots.end(); ++i) { + for (auto i=m_currentSnapshots.begin(); i!=m_currentSnapshots.end(); ++i) { delete i->second; i->second = nullptr; } - for (auto i = m_newObjectSnapshots.begin(); i!=m_newObjectSnapshots.end(); ++i) { + for (auto i=m_newObjectSnapshots.begin(); i!=m_newObjectSnapshots.end(); ++i) { delete i->second; i->second = nullptr; } - for (auto i = m_newCharacterSnapshots.begin(); i!=m_newCharacterSnapshots.end(); ++i) { - delete i->second; - i->second = nullptr; + for (auto i=m_savingCharacterSnapshots.begin(); i!=m_savingCharacterSnapshots.end(); ++i) { + delete *i; + *i = nullptr; } - for (auto i = m_objectSnapshotMap.begin(); i!=m_objectSnapshotMap.end(); ++i) { - delete i->second; - i->second = nullptr; - } - - for (auto i = m_savingSnapshots.begin(); i!=m_savingSnapshots.end(); ++i) { - delete *i; - *i = nullptr; - } - - for (auto i = m_savingCharacterSnapshots.begin(); i!=m_savingCharacterSnapshots.end(); ++i) { - delete *i; - *i = nullptr; - } + for (auto i=m_savingSnapshots.begin(); i!=m_savingSnapshots.end(); ++i) { + delete *i; + *i = nullptr; + } m_currentSnapshots.clear(); m_newObjectSnapshots.clear(); m_objectSnapshotMap.clear(); - - delete m_messageSnapshot; - delete m_commoditiesSnapshot; - delete m_arbitraryGameDataSnapshot; + m_savingCharacterSnapshots.clear(); + m_savingSnapshots.clear(); + m_messageSnapshot = nullptr; m_commoditiesSnapshot = nullptr; @@ -628,10 +617,23 @@ void Persister::endBaselines(const NetworkId &objectId, uint32 serverId) void Persister::saveCompleted(Snapshot *completedSnapshot) { - SnapshotListType::iterator i=std::remove(m_savingSnapshots.begin(),m_savingSnapshots.end(),completedSnapshot); + { + std::lock_guard lck(m_savingDeleting_mtx); + + delete completedSnapshot; + completedSnapshot = nullptr; + } + auto i=std::remove(m_savingSnapshots.begin(),m_savingSnapshots.end(),completedSnapshot); + if (i!=m_savingSnapshots.end()) { - m_savingSnapshots.erase(i, m_savingSnapshots.end()); + + { + std::lock_guard lck(m_savingDeleting_mtx); + WARNING(true, ("m_SavingSnapshots is not empty and we're nuking everything for some reason. Is this a leak?")); + m_savingSnapshots.erase(i, m_savingSnapshots.end()); + } + if (m_savingSnapshots.empty() && ConfigServerDatabase::getReportSaveTimes()) { int saveTime = Clock::timeMs() - m_saveStartTime; @@ -639,7 +641,7 @@ void Persister::saveCompleted(Snapshot *completedSnapshot) m_totalSaveTime += saveTime; if (saveTime > m_maxSaveTime) m_maxSaveTime = saveTime; - + DEBUG_REPORT_LOG(true,("Save completed in %i. (Average %i, max %i)\n", saveTime, m_totalSaveTime/m_saveCount, m_maxSaveTime)); LOG("SaveTimes",("Save completed in %i. (Average %i, max %i)", saveTime, m_totalSaveTime/m_saveCount, m_maxSaveTime)); m_lastSaveTime = saveTime; @@ -652,7 +654,7 @@ void Persister::saveCompleted(Snapshot *completedSnapshot) DatabaseProcess::getInstance().sendToCentralServer(saveCompleteMessage, true); LOG("Database",("Sending DatabaseSaveComplete network message to Central.")); } - + { // set the last save completion time (for the monitoring program) time_t theTime = time(0); @@ -661,10 +663,13 @@ void Persister::saveCompleted(Snapshot *completedSnapshot) } else { - SnapshotListType::iterator j=std::remove(m_savingCharacterSnapshots.begin(),m_savingCharacterSnapshots.end(),completedSnapshot); -DEBUG_FATAL(i==m_savingCharacterSnapshots.end(),("Programmer bug: SaveCompleted() called with a snapshot that wasn't in m_savingSnapshots or m_savingCharacterSnapshots.")); - m_savingCharacterSnapshots.erase(j, m_savingCharacterSnapshots.end()); - DEBUG_REPORT_LOG(ConfigServerDatabase::getReportSaveTimes(),("New character save completed\n")); + std::lock_guard lck(m_savingDeleting_mtx); + + auto j=std::remove(m_savingCharacterSnapshots.begin(),m_savingCharacterSnapshots.end(),completedSnapshot); + + WARNING(j==m_savingCharacterSnapshots.end(),("saveCompleted() called w/o snap in m_savingSnapshots or m_savingCharacterSnapshots.")); + + m_savingCharacterSnapshots.erase(j, m_savingCharacterSnapshots.end()); } } diff --git a/engine/server/library/serverDatabase/src/shared/Persister.h b/engine/server/library/serverDatabase/src/shared/Persister.h index 9cc76ac8..24cf49b7 100755 --- a/engine/server/library/serverDatabase/src/shared/Persister.h +++ b/engine/server/library/serverDatabase/src/shared/Persister.h @@ -16,6 +16,8 @@ #include #include //TODO: remove when we clean up newCharacterLock hack +#include + #include "Unicode.h" #include "serverNetworkMessages/MessageToPayload.h" #include "sharedDatabaseInterface/DbModeQuery.h" @@ -116,8 +118,12 @@ class Persister : public MessageDispatch::Receiver ServerSnapshotMap m_newCharacterSnapshots; ObjectSnapshotMap m_objectSnapshotMap; PendingCharactersType m_pendingCharacters; + SnapshotListType m_savingSnapshots; SnapshotListType m_savingCharacterSnapshots; + + std::mutex m_savingDeleting_mtx; + NewCharacterLockType m_newCharacterLock; CharactersToDeleteType * m_charactersToDeleteThisSaveCycle; CharactersToDeleteType * m_charactersToDeleteNextSaveCycle; diff --git a/engine/server/library/serverGame/src/shared/core/ConfigServerGame.cpp b/engine/server/library/serverGame/src/shared/core/ConfigServerGame.cpp index 7371dbf9..582593d3 100755 --- a/engine/server/library/serverGame/src/shared/core/ConfigServerGame.cpp +++ b/engine/server/library/serverGame/src/shared/core/ConfigServerGame.cpp @@ -71,7 +71,7 @@ void ConfigServerGame::install(void) KEY_INT (scriptWatcherInterruptTime, 5000); KEY_INT (scriptStackErrorLimit, 35); KEY_INT (scriptStackErrorLevel, 0); - KEY_BOOL (disableObjvarNullCheck, false); + KEY_BOOL (disableObjvarNullCheck, true); KEY_INT (maxGameServerToSendUniverseData, 1000000); KEY_INT (timeoutToAckUniverseDataReceived, 0); KEY_BOOL (disableCombat, false); diff --git a/game/server/application/SwgDatabaseServer/src/shared/buffers/ObjvarBuffer.cpp b/game/server/application/SwgDatabaseServer/src/shared/buffers/ObjvarBuffer.cpp index c0e0a5bf..5fdd99e5 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/buffers/ObjvarBuffer.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/buffers/ObjvarBuffer.cpp @@ -38,6 +38,8 @@ ObjvarBuffer::ObjvarBuffer(DB::ModeQuery::Mode mode, ObjectTableBuffer *objectTa ObjvarBuffer::~ObjvarBuffer() { + m_data.clear(); + m_overrides.clear(); } bool ObjvarBuffer::load(DB::Session *session,const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase) @@ -62,16 +64,14 @@ bool ObjvarBuffer::load(DB::Session *session,const DB::TagSet &tags, const std:: { break; } - - IndexKey key(row->object_id.getValue(), row->name_id.getValue()); - ObjvarValue value; - value.m_type=row->type.getValue(); - - // The string is stored in the database as utf8, so a wide-to-narrow is appropriate - value.m_value=Unicode::wideToNarrow(row->value.getValue()); - - value.m_detached=false; + IndexKey key(row->object_id.getValue(), row->name_id.getValue()); + ObjvarValue value; + value.m_type=row->type.getValue(); + + // The string is stored in the database as utf8, so a wide-to-narrow is appropriate + value.m_value=Unicode::wideToNarrow(row->value.getValue()); + m_data.insert(std::make_pair(key,value)); } } @@ -312,8 +312,9 @@ void ObjvarBuffer::updateObjvars(const NetworkId &objectId, const std::vectorsecond.m_type = i->value.getType(); - row->second.m_detached = true; + row->second.m_detached = true; //why the fuck even store it at this point? } + break; } @@ -330,9 +331,12 @@ void ObjvarBuffer::updateObjvars(const NetworkId &objectId, const std::vectorfirst.m_objectId==object) + while (i!=m_data.end()) { - i = m_data.erase(i); + if (i->first.m_objectId==object) + i = m_data.erase(i); + else + ++i; } } diff --git a/game/server/application/SwgDatabaseServer/src/shared/buffers/ObjvarBuffer.h b/game/server/application/SwgDatabaseServer/src/shared/buffers/ObjvarBuffer.h index 1d14df7d..2ee2f91a 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/buffers/ObjvarBuffer.h +++ b/game/server/application/SwgDatabaseServer/src/shared/buffers/ObjvarBuffer.h @@ -57,7 +57,7 @@ public: private: struct IndexKey { - NetworkId m_objectId; + const NetworkId m_objectId; int m_nameId; IndexKey(const NetworkId &objectId, int nameId); @@ -92,9 +92,7 @@ public: // ====================================================================== -inline ObjvarBuffer::IndexKey::IndexKey(const NetworkId &objectId, int nameId) : - m_objectId(objectId), - m_nameId(nameId) +inline ObjvarBuffer::IndexKey::IndexKey(const NetworkId &objectId, int nameId) : m_objectId(objectId), m_nameId(nameId) { } diff --git a/game/server/application/SwgDatabaseServer/src/shared/core/SwgDatabaseServer.cpp b/game/server/application/SwgDatabaseServer/src/shared/core/SwgDatabaseServer.cpp index 0e331f8c..10e89ee3 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/core/SwgDatabaseServer.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/core/SwgDatabaseServer.cpp @@ -61,8 +61,6 @@ void SwgDatabaseServer::run() DataCleanupManager cleanupManager; cleanupManager.runDailyCleanup(); - - DatabaseProcess::run(); } diff --git a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp index f81f75ad..ea1b4ee3 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp +++ b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.cpp @@ -139,7 +139,9 @@ SwgSnapshot::SwgSnapshot(DB::ModeQuery::Mode mode, bool useGoldDatabase) : // ---------------------------------------------------------------------- -SwgSnapshot::~SwgSnapshot(){} +SwgSnapshot::~SwgSnapshot(){ + +} // ---------------------------------------------------------------------- diff --git a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h index e2494000..73be48c3 100755 --- a/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h +++ b/game/server/application/SwgDatabaseServer/src/shared/core/SwgSnapshot.h @@ -119,7 +119,7 @@ public: void newMissionObject (NetworkId const & objectId); void newPlanetObject (NetworkId const & objectId); void newPlayerObject (NetworkId const & objectId); - void newPlayerQuestObject (NetworkId const & objectId); + void newPlayerQuestObject (NetworkId const & objectId); void newRegionCircleObject (NetworkId const & objectId); void newRegionObject (NetworkId const & objectId); void newRegionRectangleObject (NetworkId const & objectId);