- Use ACE_Future and ACE_Future_Set for async SQL queries with callback
* Callbacks will now be executed from the thread and object that scheduled the request, instead of the world runnable thread (and thus are no longer dependent on the 50ms forced sleep time).
* This design gets rid of a potential DOS loophole in the resultqueue system - unique requests will be cancelled when re-requested.
- Drop now redundant SQLQueryTask, SQLResultQueue, SQLResultQueueTask operations.
- Drop now redundant CharacterHandler class
- Change static callback functions in WorldSession to normal functions.

Thanks to Derex and Zor for advice along the way.

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-08-18 19:48:51 +02:00
parent 2ffe785765
commit d845a903b1
15 changed files with 303 additions and 862 deletions
+20 -19
View File
@@ -54,7 +54,6 @@
#include "VMapFactory.h"
#include "GameEventMgr.h"
#include "PoolMgr.h"
#include "AsyncDatabaseImpl.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
#include "InstanceSaveMgr.h"
@@ -103,7 +102,6 @@ World::World()
m_maxQueuedSessionCount = 0;
m_PlayerCount = 0;
m_MaxPlayerCount = 0;
m_resultQueue = NULL;
m_NextDailyQuestReset = 0;
m_NextWeeklyQuestReset = 0;
m_scheduledScripts = 0;
@@ -134,8 +132,6 @@ World::~World()
VMAP::VMapFactory::clear();
delete m_resultQueue;
//TODO free addSessQueue
}
@@ -1979,8 +1975,8 @@ void World::Update(uint32 diff)
RecordTimeDiff("UpdateLFGMgr");
// execute callbacks from sql queries that were queued recently
UpdateResultQueue();
RecordTimeDiff("UpdateResultQueue");
ProcessQueryCallbacks();
RecordTimeDiff("ProcessQueryCallbacks");
///- Erase corpses once every 20 minutes
if (m_timers[WUPDATE_CORPSES].Passed())
@@ -2500,21 +2496,12 @@ void World::SendRNDBroadcast()
}
}
void World::InitResultQueue()
{
m_resultQueue = new SQLResultQueue;
CharacterDatabase.SetResultQueue(m_resultQueue);
}
void World::UpdateResultQueue()
{
m_resultQueue->Update();
}
void World::UpdateRealmCharCount(uint32 accountId)
{
CharacterDatabase.AsyncPQuery(this, &World::_UpdateRealmCharCount, accountId,
"SELECT COUNT(guid) FROM characters WHERE account = '%u'", accountId);
m_realmCharCallback.SetParam(accountId);
m_realmCharCallback.SetFutureResult(
LoginDatabase.AsyncPQuery("SELECT COUNT(guid) FROM characters WHERE account = '%u'", accountId)
);
}
void World::_UpdateRealmCharCount(QueryResult_AutoPtr resultCharCount, uint32 accountId)
@@ -2742,3 +2729,17 @@ uint64 World::getWorldState(uint32 index) const
WorldStatesMap::const_iterator it = m_worldstates.find(index);
return it != m_worldstates.end() ? it->second : 0;
}
void World::ProcessQueryCallbacks()
{
QueryResult_AutoPtr result;
//-UpdateRealmCharCount
if (m_realmCharCallback.IsReady())
{
uint32 param = m_realmCharCallback.GetParam();
m_realmCharCallback.GetResult(result);
_UpdateRealmCharCount(result, param);
m_realmCharCallback.FreeResult();
}
}
+5 -5
View File
@@ -31,6 +31,7 @@
#include "SharedDefines.h"
#include "ace/Atomic_Op.h"
#include "QueryResult.h"
#include "Callback.h"
#include <map>
#include <set>
@@ -42,7 +43,6 @@ class WorldSession;
class Player;
struct ScriptAction;
struct ScriptInfo;
class SQLResultQueue;
class QueryResult;
class WorldSocket;
class SystemMgr;
@@ -670,9 +670,6 @@ class World
void ProcessCliCommands();
void QueueCliCommand(CliCommandHolder* commandHolder) { cliCmdQueue.add(commandHolder); }
void UpdateResultQueue();
void InitResultQueue();
void ForceGameEventUpdate();
void UpdateRealmCharCount(uint32 accid);
@@ -768,7 +765,6 @@ class World
// CLI command holder to be thread safe
ACE_Based::LockedQueue<CliCommandHolder*,ACE_Thread_Mutex> cliCmdQueue;
SQLResultQueue *m_resultQueue;
// next daily quests and random bg reset time
time_t m_NextDailyQuestReset;
@@ -787,6 +783,10 @@ class World
std::string m_CreatureEventAIVersion;
std::list<std::string> m_Autobroadcasts;
private:
void ProcessQueryCallbacks();
QueryCallback<uint32> m_realmCharCallback;
};
extern uint32 realmID;