aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp1
-rw-r--r--src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp102
-rw-r--r--src/server/game/Server/Protocol/Handlers/MiscHandler.cpp48
-rw-r--r--src/server/game/Server/Protocol/Handlers/QueryHandler.cpp43
-rw-r--r--src/server/game/Server/WorldSession.cpp62
-rw-r--r--src/server/game/Server/WorldSession.h19
-rw-r--r--src/server/game/World/World.cpp39
-rw-r--r--src/server/game/World/World.h10
-rw-r--r--src/server/shared/Database/AsyncDatabaseImpl.h250
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.cpp26
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.h53
-rw-r--r--src/server/shared/Database/SQLOperation.cpp48
-rw-r--r--src/server/shared/Database/SQLOperation.h33
-rw-r--r--src/server/shared/Threading/Callback.h427
-rw-r--r--src/server/worldserver/WorldThread/WorldRunnable.cpp2
15 files changed, 302 insertions, 861 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index cb67ceef630..8d23f9a472c 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -59,7 +59,6 @@
#include "OutdoorPvPMgr.h"
#include "ArenaTeam.h"
#include "Chat.h"
-#include "AsyncDatabaseImpl.h"
#include "Spell.h"
#include "SocialMgr.h"
#include "GameEventMgr.h"
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
index 2a764a366e8..01c1392f35b 100644
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
@@ -27,7 +27,6 @@
#include "WorldSession.h"
#include "MD5.h"
#include "DatabaseEnv.h"
-#include "AsyncDatabaseImpl.h"
#include "ArenaTeam.h"
#include "Chat.h"
@@ -103,33 +102,6 @@ bool LoginQueryHolder::Initialize()
return res;
}
-// don't call WorldSession directly
-// it may get deleted before the query callbacks get executed
-// instead pass an account id to this handler
-class CharacterHandler
-{
-
- public:
- void HandleCharEnumCallback(QueryResult_AutoPtr result, uint32 account)
- {
- WorldSession * session = sWorld.FindSession(account);
- if (!session)
- return;
- session->HandleCharEnum(result);
- }
- void HandlePlayerLoginCallback(QueryResult_AutoPtr /*dummy*/, SQLQueryHolder * holder)
- {
- if (!holder) return;
- WorldSession *session = sWorld.FindSession(((LoginQueryHolder*)holder)->GetAccountId());
- if (!session)
- {
- delete holder;
- return;
- }
- session->HandlePlayerLogin((LoginQueryHolder*)holder);
- }
-} chrHandler;
-
void WorldSession::HandleCharEnum(QueryResult_AutoPtr result)
{
WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
@@ -158,31 +130,33 @@ void WorldSession::HandleCharEnum(QueryResult_AutoPtr result)
void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/)
{
/// get all the data necessary for loading all characters (along with their pets) on the account
- CharacterDatabase.AsyncPQuery(&chrHandler, &CharacterHandler::HandleCharEnumCallback, GetAccountId(),
- !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
- // ------- Query Without Declined Names --------
- // 0 1 2 3 4 5 6 7
- "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
- // 8 9 10 11 12 13 14
- "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
- // 15 16 17 18 19
- "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache "
- "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
- "LEFT JOIN guild_member ON characters.guid = guild_member.guid "
- "WHERE characters.account = '%u' ORDER BY characters.guid"
- :
- // --------- Query With Declined Names ---------
- // 0 1 2 3 4 5 6 7
- "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
- // 8 9 10 11 12 13 14
- "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
- // 15 16 17 18 19 20
- "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_declinedname.genitive "
- "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
- "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
- "LEFT JOIN guild_member ON characters.guid = guild_member.guid "
- "WHERE characters.account = '%u' ORDER BY characters.guid",
- PET_SAVE_AS_CURRENT,GetAccountId());
+ m_charEnumCallback =
+ CharacterDatabase.AsyncPQuery(
+ !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
+ // ------- Query Without Declined Names --------
+ // 0 1 2 3 4 5 6 7
+ "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
+ // 8 9 10 11 12 13 14
+ "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
+ // 15 16 17 18 19
+ "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache "
+ "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
+ "LEFT JOIN guild_member ON characters.guid = guild_member.guid "
+ "WHERE characters.account = '%u' ORDER BY characters.guid"
+ :
+ // --------- Query With Declined Names ---------
+ // 0 1 2 3 4 5 6 7
+ "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
+ // 8 9 10 11 12 13 14
+ "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
+ // 15 16 17 18 19 20
+ "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_declinedname.genitive "
+ "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
+ "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
+ "LEFT JOIN guild_member ON characters.guid = guild_member.guid "
+ "WHERE characters.account = '%u' ORDER BY characters.guid",
+ PET_SAVE_AS_CURRENT, GetAccountId()
+ );
}
void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data)
@@ -565,7 +539,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket & recv_data)
return;
}
- CharacterDatabase.DelayQueryHolder(&chrHandler, &CharacterHandler::HandlePlayerLoginCallback, holder);
+ m_charLoginCallback = CharacterDatabase.DelayQueryHolder((SQLQueryHolder*)holder);
}
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
@@ -957,24 +931,22 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
// make sure that the character belongs to the current account, that rename at login is enabled
// and that there is no character with the desired new name
- CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack,
- GetAccountId(), newname,
+ m_charRenameCallback.SetParam(newname);
+ m_charRenameCallback.SetFutureResult(
+ CharacterDatabase.AsyncPQuery(
"SELECT guid, name FROM characters WHERE guid = %d AND account = %d AND (at_login & %d) = %d AND NOT EXISTS (SELECT NULL FROM characters WHERE name = '%s')",
GUID_LOPART(guid), GetAccountId(), AT_LOGIN_RENAME, AT_LOGIN_RENAME, escaped_newname.c_str()
-);
+ )
+ );
}
-void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string newname)
+void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, std::string newname)
{
- WorldSession * session = sWorld.FindSession(accountId);
- if (!session)
- return;
-
if (!result)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_CREATE_ERROR);
- session->SendPacket(&data);
+ SendPacket(&data);
return;
}
@@ -985,13 +957,13 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr resu
CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
- sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
+ sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
data << uint8(RESPONSE_SUCCESS);
data << uint64(guid);
data << newname;
- session->SendPacket(&data);
+ SendPacket(&data);
}
void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data)
diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
index 79e3374c975..5d5ffc39417 100644
--- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
@@ -21,7 +21,6 @@
#include "Common.h"
#include "Language.h"
#include "DatabaseEnv.h"
-#include "AsyncDatabaseImpl.h"
#include "WorldPacket.h"
#include "Opcodes.h"
#include "Log.h"
@@ -554,21 +553,19 @@ void WorldSession::HandleAddFriendOpcode(WorldPacket & recv_data)
sLog.outDebug("WORLD: %s asked to add friend : '%s'",
GetPlayer()->GetName(), friendName.c_str());
- CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddFriendOpcodeCallBack, GetAccountId(), friendNote, "SELECT guid, race, account FROM characters WHERE name = '%s'", friendName.c_str());
+ m_addFriendCallback.SetParam(friendNote);
+ m_addFriendCallback.SetFutureResult(
+ CharacterDatabase.AsyncPQuery("SELECT guid, race, account FROM characters WHERE name = '%s'", friendName.c_str())
+ );
}
-void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string friendNote)
+void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, std::string friendNote)
{
uint64 friendGuid;
uint64 friendAcctid;
uint32 team;
FriendsResult friendResult;
- WorldSession * session = sWorld.FindSession(accountId);
-
- if (!session || !session->GetPlayer())
- return;
-
friendResult = FRIEND_NOT_FOUND;
friendGuid = 0;
@@ -578,35 +575,35 @@ void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, uin
team = Player::TeamForRace((*result)[1].GetUInt8());
friendAcctid = (*result)[2].GetUInt32();
- if (session->GetSecurity() >= SEC_MODERATOR || sWorld.getConfig(CONFIG_ALLOW_GM_FRIEND) || sAccountMgr.GetSecurity(friendAcctid) < SEC_MODERATOR)
+ if (GetSecurity() >= SEC_MODERATOR || sWorld.getConfig(CONFIG_ALLOW_GM_FRIEND) || sAccountMgr.GetSecurity(friendAcctid) < SEC_MODERATOR)
{
if (friendGuid)
{
- if (friendGuid == session->GetPlayer()->GetGUID())
+ if (friendGuid == GetPlayer()->GetGUID())
friendResult = FRIEND_SELF;
- else if (session->GetPlayer()->GetTeam() != team && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && session->GetSecurity() < SEC_MODERATOR)
+ else if (GetPlayer()->GetTeam() != team && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && GetSecurity() < SEC_MODERATOR)
friendResult = FRIEND_ENEMY;
- else if (session->GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
+ else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
friendResult = FRIEND_ALREADY;
else
{
Player* pFriend = ObjectAccessor::FindPlayer(friendGuid);
- if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(session->GetPlayer()))
+ if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer()))
friendResult = FRIEND_ADDED_ONLINE;
else
friendResult = FRIEND_ADDED_OFFLINE;
- if (!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false))
+ if (!GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false))
{
friendResult = FRIEND_LIST_FULL;
- sLog.outDebug("WORLD: %s's friend list is full.", session->GetPlayer()->GetName());
+ sLog.outDebug("WORLD: %s's friend list is full.", GetPlayer()->GetName());
}
}
- session->GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote);
+ GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote);
}
}
}
- sSocialMgr.SendFriendStatus(session->GetPlayer(), friendResult, GUID_LOPART(friendGuid), false);
+ sSocialMgr.SendFriendStatus(GetPlayer(), friendResult, GUID_LOPART(friendGuid), false);
sLog.outDebug("WORLD: Sent (SMSG_FRIEND_STATUS)");
}
@@ -642,19 +639,14 @@ void WorldSession::HandleAddIgnoreOpcode(WorldPacket & recv_data)
sLog.outDebug("WORLD: %s asked to Ignore: '%s'",
GetPlayer()->GetName(), IgnoreName.c_str());
- CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddIgnoreOpcodeCallBack, GetAccountId(), "SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str());
+ m_addIgnoreCallback = CharacterDatabase.AsyncPQuery("SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str());
}
-void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId)
+void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result)
{
uint64 IgnoreGuid;
FriendsResult ignoreResult;
- WorldSession * session = sWorld.FindSession(accountId);
-
- if (!session || !session->GetPlayer())
- return;
-
ignoreResult = FRIEND_IGNORE_NOT_FOUND;
IgnoreGuid = 0;
@@ -664,22 +656,22 @@ void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result, uin
if (IgnoreGuid)
{
- if (IgnoreGuid == session->GetPlayer()->GetGUID()) //not add yourself
+ if (IgnoreGuid == GetPlayer()->GetGUID()) //not add yourself
ignoreResult = FRIEND_IGNORE_SELF;
- else if (session->GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)))
+ else if (GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)))
ignoreResult = FRIEND_IGNORE_ALREADY;
else
{
ignoreResult = FRIEND_IGNORE_ADDED;
// ignore list full
- if (!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
+ if (!GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
ignoreResult = FRIEND_IGNORE_FULL;
}
}
}
- sSocialMgr.SendFriendStatus(session->GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), false);
+ sSocialMgr.SendFriendStatus(GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), false);
sLog.outDebug("WORLD: Sent (SMSG_FRIEND_STATUS)");
}
diff --git a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
index 7cb60435d69..a830ff09ed6 100644
--- a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
@@ -21,7 +21,6 @@
#include "Common.h"
#include "Language.h"
#include "DatabaseEnv.h"
-#include "AsyncDatabaseImpl.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
@@ -61,37 +60,37 @@ void WorldSession::SendNameQueryOpcode(Player *p)
void WorldSession::SendNameQueryOpcodeFromDB(uint64 guid)
{
- CharacterDatabase.AsyncPQuery(&WorldSession::SendNameQueryOpcodeFromDBCallBack, GetAccountId(),
- !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
- // ------- Query Without Declined Names --------
- // 0 1 2 3 4
- "SELECT guid, name, race, gender, class "
- "FROM characters WHERE guid = '%u'"
- :
- // --------- Query With Declined Names ---------
- // 0 1 2 3 4
- "SELECT characters.guid, name, race, gender, class, "
- // 5 6 7 8 9
- "genitive, dative, accusative, instrumental, prepositional "
- "FROM characters LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid WHERE characters.guid = '%u'",
- GUID_LOPART(guid));
+ m_nameQueryCallbacks.insert(
+ CharacterDatabase.AsyncPQuery(
+ !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
+ // ------- Query Without Declined Names --------
+ // 0 1 2 3 4
+ "SELECT guid, name, race, gender, class "
+ "FROM characters WHERE guid = '%u'"
+ :
+ // --------- Query With Declined Names ---------
+ // 0 1 2 3 4
+ "SELECT characters.guid, name, race, gender, class, "
+ // 5 6 7 8 9
+ "genitive, dative, accusative, instrumental, prepositional "
+ "FROM characters LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid WHERE characters.guid = '%u'",
+ GUID_LOPART(guid))
+ );
+
+// CharacterDatabase.AsyncPQuery(&WorldSession::SendNameQueryOpcodeFromDBCallBack, GetAccountId(),
}
-void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result, uint32 accountId)
+void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result)
{
if (!result)
return;
- WorldSession * session = sWorld.FindSession(accountId);
- if (!session)
- return;
-
Field *fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
std::string name = fields[1].GetCppString();
uint8 pRace = 0, pGender = 0, pClass = 0;
if (name == "")
- name = session->GetTrinityString(LANG_NON_EXIST_CHARACTER);
+ name = GetTrinityString(LANG_NON_EXIST_CHARACTER);
else
{
pRace = fields[2].GetUInt8();
@@ -118,7 +117,7 @@ void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result,
else
data << uint8(0); // is not declined
- session->SendPacket(&data);
+ SendPacket(&data);
}
void WorldSession::HandleNameQueryOpcode(WorldPacket & recv_data)
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index fc63e2b6e75..9dc27b07a85 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -290,6 +290,8 @@ bool WorldSession::Update(uint32 diff)
delete packet;
}
+ ProcessQueryCallbacks();
+
time_t currTime = time(NULL);
///- If necessary, log the player out
if (ShouldLogOut(currTime) && !m_playerLoading)
@@ -955,3 +957,63 @@ void WorldSession::SetPlayer(Player *plr)
if (_player)
m_GUIDLow = _player->GetGUIDLow();
}
+
+void WorldSession::ProcessQueryCallbacks()
+{
+ QueryResult_AutoPtr result;
+
+ //! HandleNameQueryOpcode
+ while (!m_nameQueryCallbacks.is_empty())
+ {
+ QueryResultFuture lResult;
+ ACE_Time_Value timeout = ACE_Time_Value::zero;
+ if (m_nameQueryCallbacks.next_readable(lResult, &timeout) != 1)
+ break;
+
+ lResult.get(result);
+ SendNameQueryOpcodeFromDBCallBack(result);
+ }
+
+ //! HandleCharEnumOpcode
+ if (m_charEnumCallback.ready())
+ {
+ m_charEnumCallback.get(result);
+ HandleCharEnum(result);
+ m_charEnumCallback.cancel();
+ }
+
+ //! HandlePlayerLoginOpcode
+ if (m_charLoginCallback.ready())
+ {
+ SQLQueryHolder* param;
+ m_charLoginCallback.get(param);
+ HandlePlayerLogin((LoginQueryHolder*)param);
+ m_charLoginCallback.cancel();
+ }
+
+ //! HandleAddFriendOpcode
+ if (m_addFriendCallback.IsReady())
+ {
+ std::string& param = m_addFriendCallback.GetParam();
+ m_addFriendCallback.GetResult(result);
+ HandleAddFriendOpcodeCallBack(result, param);
+ m_addFriendCallback.FreeResult();
+ }
+
+ //- HandleCharRenameOpcode
+ if (m_charRenameCallback.IsReady())
+ {
+ std::string& param = m_charRenameCallback.GetParam();
+ m_charRenameCallback.GetResult(result);
+ HandleChangePlayerNameOpcodeCallBack(result, param);
+ m_charRenameCallback.FreeResult();
+ }
+
+ //- HandleCharAddIgnoreOpcode
+ if (m_addIgnoreCallback.ready())
+ {
+ m_addIgnoreCallback.get(result);
+ HandleAddIgnoreOpcodeCallBack(result);
+ m_addIgnoreCallback.cancel();
+ }
+} \ No newline at end of file
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 7251e900ae0..a8578056d5a 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -192,7 +192,7 @@ class WorldSession
//void SendTestCreatureQueryOpcode(uint32 entry, uint64 guid, uint32 testvalue);
void SendNameQueryOpcode(Player* p);
void SendNameQueryOpcodeFromDB(uint64 guid);
- static void SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result, uint32 accountId);
+ void SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result);
void SendTrainerList(uint64 guid);
void SendTrainerList(uint64 guid, const std::string& strTitle);
@@ -389,10 +389,10 @@ class WorldSession
void HandleEmoteOpcode(WorldPacket& recvPacket);
void HandleContactListOpcode(WorldPacket& recvPacket);
void HandleAddFriendOpcode(WorldPacket& recvPacket);
- static void HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string friendNote);
+ void HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, std::string friendNote);
void HandleDelFriendOpcode(WorldPacket& recvPacket);
void HandleAddIgnoreOpcode(WorldPacket& recvPacket);
- static void HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId);
+ void HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result);
void HandleDelIgnoreOpcode(WorldPacket& recvPacket);
void HandleSetContactNotesOpcode(WorldPacket& recvPacket);
void HandleBugOpcode(WorldPacket& recvPacket);
@@ -665,7 +665,7 @@ class WorldSession
void HandleSetActionBarToggles(WorldPacket& recv_data);
void HandleCharRenameOpcode(WorldPacket& recv_data);
- static void HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string newname);
+ void HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, std::string newname);
void HandleSetPlayerDeclinedNames(WorldPacket& recv_data);
void HandleTotemDestroyed(WorldPacket& recv_data);
@@ -798,6 +798,17 @@ class WorldSession
void HandleQuestPOIQuery(WorldPacket& recv_data);
void HandleEjectPasenger(WorldPacket &data);
void HandleEnterPlayerVehicle(WorldPacket &data);
+
+ private:
+ void ProcessQueryCallbacks();
+
+ QueryResultFutureSet m_nameQueryCallbacks;
+ QueryResultFuture m_charEnumCallback;
+ QueryResultFuture m_addIgnoreCallback;
+ QueryCallback<std::string> m_charRenameCallback;
+ QueryCallback<std::string> m_addFriendCallback;
+ QueryResultHolderFuture m_charLoginCallback;
+
private:
// private trade methods
void moveItems(Item* myItems[], Item* hisItems[]);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index a52d2a7d48e..c6db1e81d96 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -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();
+ }
+} \ No newline at end of file
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 2ade43c26a9..74993e6b30a 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -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;
diff --git a/src/server/shared/Database/AsyncDatabaseImpl.h b/src/server/shared/Database/AsyncDatabaseImpl.h
deleted file mode 100644
index 39a5e6551d5..00000000000
--- a/src/server/shared/Database/AsyncDatabaseImpl.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "DatabaseWorkerPool.h"
-#include "SQLOperation.h"
-
-
-/// Function body definitions for the template function members of the Database class
-
-#define ASYNC_QUERY_BODY(sql, queue_itr) \
- if (!sql) return false; \
- \
- QueryQueues::iterator queue_itr; \
- \
- { \
- ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
- queue_itr = m_queryQueues.find(queryThread); \
- if (queue_itr == m_queryQueues.end()) return false; \
- }
-
-#define ASYNC_PQUERY_BODY(format, szQuery) \
- if(!format) return false; \
- \
- char szQuery [MAX_QUERY_LEN]; \
- \
- { \
- va_list ap; \
- \
- va_start(ap, format); \
- int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); \
- va_end(ap); \
- \
- if(res==-1) \
- { \
- sLog.outError("SQL Query truncated (and not execute) for format: %s",format); \
- return false; \
- } \
- }
-
-
-#define ASYNC_DELAYHOLDER_BODY(holder, queue_itr) \
- if (!holder) return false; \
- \
- QueryQueues::iterator queue_itr; \
- \
- { \
- ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
- queue_itr = m_queryQueues.find(queryThread); \
- if (queue_itr == m_queryQueues.end()) return false; \
- }
-
-
-// -- Query / member --
-
-
-template<class Class>
-bool
-DatabaseWorkerPool::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::QueryCallback<Class>(object, method), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-template<class Class, typename ParamType1>
-bool
-DatabaseWorkerPool::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::QueryCallback<Class, ParamType1>(object, method, (QueryResult_AutoPtr)NULL, param1), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-template<class Class, typename ParamType1, typename ParamType2>
-bool
-DatabaseWorkerPool::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult_AutoPtr)NULL, param1, param2), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
-bool
-DatabaseWorkerPool::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult_AutoPtr)NULL, param1, param2, param3), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-// -- Query / static --
-
-
-template<typename ParamType1>
-bool
-DatabaseWorkerPool::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::SQueryCallback<ParamType1>(method, (QueryResult_AutoPtr)NULL, param1), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-template<typename ParamType1, typename ParamType2>
-bool
-DatabaseWorkerPool::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult_AutoPtr)NULL, param1, param2), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-template<typename ParamType1, typename ParamType2, typename ParamType3>
-bool
-DatabaseWorkerPool::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult_AutoPtr)NULL, param1, param2, param3), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-// -- PQuery / member --
-
-
-template<class Class>
-bool
-DatabaseWorkerPool::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(object, method, szQuery);
-}
-
-
-template<class Class, typename ParamType1>
-bool
-DatabaseWorkerPool::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(object, method, param1, szQuery);
-}
-
-
-template<class Class, typename ParamType1, typename ParamType2>
-bool
-DatabaseWorkerPool::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(object, method, param1, param2, szQuery);
-}
-
-
-template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
-bool
-DatabaseWorkerPool::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(object, method, param1, param2, param3, szQuery);
-}
-
-
-// -- PQuery / static --
-
-
-template<typename ParamType1>
-bool
-DatabaseWorkerPool::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(method, param1, szQuery);
-}
-
-
-template<typename ParamType1, typename ParamType2>
-bool
-DatabaseWorkerPool::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(method, param1, param2, szQuery);
-}
-
-
-template<typename ParamType1, typename ParamType2, typename ParamType3>
-bool
-DatabaseWorkerPool::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(method, param1, param2, param3, szQuery);
-}
-
-
-// -- QueryHolder --
-
-
-template<class Class>
-bool
-DatabaseWorkerPool::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SQLQueryHolder*), SQLQueryHolder *holder)
-{
- ASYNC_DELAYHOLDER_BODY(holder, itr)
- SQLQueryHolderTask *task = new SQLQueryHolderTask(holder, new Trinity::QueryCallback<Class, SQLQueryHolder*>(object, method, (QueryResult_AutoPtr)NULL, holder), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-template<class Class, typename ParamType1>
-bool
-DatabaseWorkerPool::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SQLQueryHolder*, ParamType1), SQLQueryHolder *holder, ParamType1 param1)
-{
- ASYNC_DELAYHOLDER_BODY(holder, itr)
- SQLQueryHolderTask *task = new SQLQueryHolderTask(holder, new Trinity::QueryCallback<Class, SQLQueryHolder*, ParamType1>(object, method, (QueryResult_AutoPtr)NULL, holder, param1), itr->second);
- Enqueue(task);
- return true;
-}
-
-
-#undef ASYNC_QUERY_BODY
-#undef ASYNC_PQUERY_BODY
-#undef ASYNC_DELAYHOLDER_BODY
diff --git a/src/server/shared/Database/DatabaseWorkerPool.cpp b/src/server/shared/Database/DatabaseWorkerPool.cpp
index 849fd67d8c0..2e50f6bf8fa 100644
--- a/src/server/shared/Database/DatabaseWorkerPool.cpp
+++ b/src/server/shared/Database/DatabaseWorkerPool.cpp
@@ -197,6 +197,32 @@ void DatabaseWorkerPool::CommitTransaction()
}
}
+QueryResultFuture DatabaseWorkerPool::AsyncQuery(const char* sql)
+{
+ QueryResultFuture res;
+ BasicStatementTask* task = new BasicStatementTask(sql, res);
+ Enqueue(task);
+ return res; //! Fool compiler, has no use yet
+}
+
+QueryResultFuture DatabaseWorkerPool::AsyncPQuery(const char* sql, ...)
+{
+ va_list ap;
+ char szQuery[MAX_QUERY_LEN];
+ va_start(ap, sql);
+ int res = vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
+ va_end(ap);
+
+ return AsyncQuery(szQuery);
+}
+
+QueryResultHolderFuture DatabaseWorkerPool::DelayQueryHolder(SQLQueryHolder* holder)
+{
+ QueryResultHolderFuture res;
+ SQLQueryHolderTask* task = new SQLQueryHolderTask(holder, res);
+ Enqueue(task);
+ return res; //! Fool compiler, has no use yet
+}
MySQLConnection* DatabaseWorkerPool::GetConnection()
{
diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h
index 06374e44143..c1c645e088e 100644
--- a/src/server/shared/Database/DatabaseWorkerPool.h
+++ b/src/server/shared/Database/DatabaseWorkerPool.h
@@ -26,6 +26,7 @@
#include "SQLOperation.h"
#include "QueryResult.h"
+#include "Callback.h"
#include "MySQLConnection.h"
enum MySQLThreadBundle
@@ -56,52 +57,10 @@ class DatabaseWorkerPool
void DirectPExecute(const char* sql, ...);
QueryResult_AutoPtr Query(const char* sql);
QueryResult_AutoPtr PQuery(const char* sql, ...);
-
- /// Async queries and query holders, implemented in DatabaseImpl.h
-
- // Query / member
- template<class Class>
- bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *sql);
- template<class Class, typename ParamType1>
- bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql);
- template<class Class, typename ParamType1, typename ParamType2>
- bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
- template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
- bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
- // Query / static
- template<typename ParamType1>
- bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql);
- template<typename ParamType1, typename ParamType2>
- bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
- template<typename ParamType1, typename ParamType2, typename ParamType3>
- bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
- // PQuery / member
- template<class Class>
- bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *format,...) ATTR_PRINTF(4,5);
- template<class Class, typename ParamType1>
- bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
- template<class Class, typename ParamType1, typename ParamType2>
- bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(6,7);
- template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
- bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(7,8);
- // PQuery / static
- template<typename ParamType1>
- bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(4,5);
- template<typename ParamType1, typename ParamType2>
- bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
- template<typename ParamType1, typename ParamType2, typename ParamType3>
- bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(6,7);
- template<class Class>
- // QueryHolder
- bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SQLQueryHolder*), SQLQueryHolder *holder);
- template<class Class, typename ParamType1>
- bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SQLQueryHolder*, ParamType1), SQLQueryHolder *holder, ParamType1 param1);
-
- void SetResultQueue(SQLResultQueue * queue)
- {
- m_queryQueues[ACE_Based::Thread::current()] = queue;
- }
-
+ QueryResultFuture AsyncQuery(const char* sql);
+ QueryResultFuture AsyncPQuery(const char* sql, ...);
+ QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder);
+
void BeginTransaction();
void RollbackTransaction();
void CommitTransaction();
@@ -135,7 +94,6 @@ class DatabaseWorkerPool
private:
typedef UNORDERED_MAP<ACE_Based::Thread*, MySQLConnection*> ConnectionMap;
typedef UNORDERED_MAP<ACE_Based::Thread*, TransactionTask*> TransactionQueues;
- typedef UNORDERED_MAP<ACE_Based::Thread*, SQLResultQueue*> QueryQueues;
typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, uint32> AtomicUInt;
private:
@@ -149,7 +107,6 @@ class DatabaseWorkerPool
std::string m_infoString; //! Infostring that is passed on to child connections.
TransactionQueues m_tranQueues; //! Transaction queues from diff. threads
ACE_Thread_Mutex m_transQueues_mtx; //! To guard m_transQueues
- QueryQueues m_queryQueues; //! Query queues from diff threads
};
#endif
diff --git a/src/server/shared/Database/SQLOperation.cpp b/src/server/shared/Database/SQLOperation.cpp
index c9e3ba3e937..35a61dc9518 100644
--- a/src/server/shared/Database/SQLOperation.cpp
+++ b/src/server/shared/Database/SQLOperation.cpp
@@ -21,7 +21,15 @@
#include "Log.h"
/*! Basic, ad-hoc queries. */
-BasicStatementTask::BasicStatementTask(const char* sql)
+BasicStatementTask::BasicStatementTask(const char* sql) :
+m_has_result(false)
+{
+ m_sql = strdup(sql);
+}
+
+BasicStatementTask::BasicStatementTask(const char* sql, QueryResultFuture result) :
+m_result(result),
+m_has_result(true)
{
m_sql = strdup(sql);
}
@@ -33,6 +41,15 @@ BasicStatementTask::~BasicStatementTask()
bool BasicStatementTask::Execute()
{
+ if (m_has_result)
+ {
+ m_result.set(
+ m_conn->Query(m_sql)
+ );
+
+ return true;
+ }
+
return m_conn->Execute(m_sql);
}
@@ -83,18 +100,6 @@ bool TransactionTask::Execute()
return true;
}
-/*! Callback statements/holders */
-void SQLResultQueue::Update()
-{
- /// execute the callbacks waiting in the synchronization queue
- Trinity::IQueryCallback* callback;
- while (next(callback))
- {
- callback->Execute();
- delete callback;
- }
-}
-
bool SQLQueryHolder::SetQuery(size_t index, const char *sql)
{
if (m_queries.size() <= index)
@@ -181,7 +186,7 @@ void SQLQueryHolder::SetSize(size_t size)
bool SQLQueryHolderTask::Execute()
{
- if (!m_holder || !m_callback || !m_queue)
+ if (!m_holder)
return false;
/// we can do this, we are friends
@@ -195,19 +200,6 @@ bool SQLQueryHolderTask::Execute()
m_holder->SetResult(i, m_conn->Query(sql));
}
- /// sync with the caller thread
- m_queue->add(m_callback);
- return true;
-}
-
-bool SQLQueryTask::Execute()
-{
- if (!m_callback || !m_queue)
- return false;
-
- /// execute the query and store the result in the callback
- m_callback->SetResult(m_conn->Query(m_sql));
- /// add the callback to the sql result queue of the thread it originated from
- m_queue->add(m_callback);
+ m_result.set(m_holder);
return true;
}
diff --git a/src/server/shared/Database/SQLOperation.h b/src/server/shared/Database/SQLOperation.h
index 4833e28164e..0bf08d3e3eb 100644
--- a/src/server/shared/Database/SQLOperation.h
+++ b/src/server/shared/Database/SQLOperation.h
@@ -43,17 +43,21 @@ class SQLOperation : public ACE_Method_Request
MySQLConnection* m_conn;
};
+typedef ACE_Future<QueryResult_AutoPtr> QueryResultFuture;
/*! Raw, ad-hoc query. */
class BasicStatementTask : public SQLOperation
{
public:
BasicStatementTask(const char* sql);
+ BasicStatementTask(const char* sql, QueryResultFuture result);
~BasicStatementTask();
bool Execute();
private:
const char* m_sql; //- Raw query to be executed
+ bool m_has_result;
+ QueryResultFuture m_result;
};
/*! Transactions */
@@ -70,14 +74,6 @@ class TransactionTask : public SQLOperation
std::queue<char*> m_queries;
};
-/*! ResultQueue */
-class SQLResultQueue : public ACE_Based::LockedQueue<Trinity::IQueryCallback* , ACE_Thread_Mutex>
-{
- public:
- SQLResultQueue() {}
- void Update();
-};
-
class SQLQueryHolder
{
friend class SQLQueryHolderTask;
@@ -94,28 +90,17 @@ class SQLQueryHolder
void SetResult(size_t index, QueryResult_AutoPtr result);
};
+typedef ACE_Future<SQLQueryHolder*> QueryResultHolderFuture;
+
class SQLQueryHolderTask : public SQLOperation
{
private:
SQLQueryHolder * m_holder;
- Trinity::IQueryCallback * m_callback;
- SQLResultQueue * m_queue;
- public:
- SQLQueryHolderTask(SQLQueryHolder *holder, Trinity::IQueryCallback * callback, SQLResultQueue * queue)
- : m_holder(holder), m_callback(callback), m_queue(queue) {}
- bool Execute();
-};
+ QueryResultHolderFuture m_result;
-class SQLQueryTask : public SQLOperation
-{
- private:
- const char *m_sql;
- Trinity::IQueryCallback * m_callback;
- SQLResultQueue * m_queue;
public:
- SQLQueryTask(const char *sql, Trinity::IQueryCallback * callback, SQLResultQueue * queue)
- : m_sql(strdup(sql)), m_callback(callback), m_queue(queue) {}
- ~SQLQueryTask() { void* tofree = const_cast<char*>(m_sql); free(tofree); }
+ SQLQueryHolderTask(SQLQueryHolder *holder, QueryResultHolderFuture res)
+ : m_holder(holder), m_result(res){};
bool Execute();
};
diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h
index d2e2c36851a..921741bbed4 100644
--- a/src/server/shared/Threading/Callback.h
+++ b/src/server/shared/Threading/Callback.h
@@ -1,6 +1,4 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
@@ -10,377 +8,76 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef TRINITY_CALLBACK_H
-#define TRINITY_CALLBACK_H
-
-/// ------------ BASE CLASSES ------------
-
-namespace Trinity
-{
- template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
- class _Callback
- {
- protected:
- typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3, ParamType4);
- Class *m_object;
- Method m_method;
- ParamType1 m_param1;
- ParamType2 m_param2;
- ParamType3 m_param3;
- ParamType4 m_param4;
- void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3, m_param4); }
- public:
- _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
- : m_object(object), m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {}
- _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4> const& cb)
- : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {}
- };
-
- template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 >
- class _Callback < Class, ParamType1, ParamType2, ParamType3 >
- {
- protected:
- typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3);
- Class *m_object;
- Method m_method;
- ParamType1 m_param1;
- ParamType2 m_param2;
- ParamType3 m_param3;
- void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3); }
- public:
- _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
- : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {}
- _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3 > const& cb)
- : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
- };
-
- template < class Class, typename ParamType1, typename ParamType2 >
- class _Callback < Class, ParamType1, ParamType2 >
- {
- protected:
- typedef void (Class::*Method)(ParamType1, ParamType2);
- Class *m_object;
- Method m_method;
- ParamType1 m_param1;
- ParamType2 m_param2;
- void _Execute() { (m_object->*m_method)(m_param1, m_param2); }
- public:
- _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2)
- : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {}
- _Callback(_Callback < Class, ParamType1, ParamType2 > const& cb)
- : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {}
- };
-
- template < class Class, typename ParamType1 >
- class _Callback < Class, ParamType1 >
- {
- protected:
- typedef void (Class::*Method)(ParamType1);
- Class *m_object;
- Method m_method;
- ParamType1 m_param1;
- void _Execute() { (m_object->*m_method)(m_param1); }
- public:
- _Callback(Class *object, Method method, ParamType1 param1)
- : m_object(object), m_method(method), m_param1(param1) {}
- _Callback(_Callback < Class, ParamType1 > const& cb)
- : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1) {}
- };
-
- template < class Class >
- class _Callback < Class >
- {
- protected:
- typedef void (Class::*Method)();
- Class *m_object;
- Method m_method;
- void _Execute() { (m_object->*m_method)(); }
- public:
- _Callback(Class *object, Method method)
- : m_object(object), m_method(method) {}
- _Callback(_Callback < Class > const& cb)
- : m_object(cb.m_object), m_method(cb.m_method) {}
- };
-
- /// ---- Statics ----
-
- template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
- class _SCallback
- {
- protected:
- typedef void (*Method)(ParamType1, ParamType2, ParamType3, ParamType4);
- Method m_method;
- ParamType1 m_param1;
- ParamType2 m_param2;
- ParamType3 m_param3;
- ParamType4 m_param4;
- void _Execute() { (*m_method)(m_param1, m_param2, m_param3, m_param4); }
- public:
- _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
- : m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {}
- _SCallback(_SCallback < ParamType1, ParamType2, ParamType3, ParamType4> const& cb)
- : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {}
- };
-
- template < typename ParamType1, typename ParamType2, typename ParamType3 >
- class _SCallback < ParamType1, ParamType2, ParamType3 >
- {
- protected:
- typedef void (*Method)(ParamType1, ParamType2, ParamType3);
- Method m_method;
- ParamType1 m_param1;
- ParamType2 m_param2;
- ParamType3 m_param3;
- void _Execute() { (*m_method)(m_param1, m_param2, m_param3); }
- public:
- _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
- : m_method(method), m_param1(param1), m_param2(param2), m_param3(param3) {}
- _SCallback(_SCallback < ParamType1, ParamType2, ParamType3 > const& cb)
- : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
- };
-
- template < typename ParamType1, typename ParamType2 >
- class _SCallback < ParamType1, ParamType2 >
- {
- protected:
- typedef void (*Method)(ParamType1, ParamType2);
- Method m_method;
- ParamType1 m_param1;
- ParamType2 m_param2;
- void _Execute() { (*m_method)(m_param1, m_param2); }
- public:
- _SCallback(Method method, ParamType1 param1, ParamType2 param2)
- : m_method(method), m_param1(param1), m_param2(param2) {}
- _SCallback(_SCallback < ParamType1, ParamType2 > const& cb)
- : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {}
- };
-
- template < typename ParamType1 >
- class _SCallback < ParamType1 >
- {
- protected:
- typedef void (*Method)(ParamType1);
- Method m_method;
- ParamType1 m_param1;
- void _Execute() { (*m_method)(m_param1); }
- public:
- _SCallback(Method method, ParamType1 param1)
- : m_method(method), m_param1(param1) {}
- _SCallback(_SCallback < ParamType1 > const& cb)
- : m_method(cb.m_method), m_param1(cb.m_param1) {}
- };
-
- template < >
- class _SCallback < >
- {
- protected:
- typedef void (*Method)();
- Method m_method;
- void _Execute() { (*m_method)(); }
- public:
- _SCallback(Method method)
- : m_method(method) {}
- _SCallback(_SCallback <> const& cb)
- : m_method(cb.m_method) {}
- };
-}
-
-/// --------- GENERIC CALLBACKS ----------
-
-namespace Trinity
-{
- class ICallback
- {
- public:
- virtual void Execute() = 0;
- virtual ~ICallback() {}
- };
-
- template < class CB >
- class _ICallback : public CB, public ICallback
- {
- public:
- _ICallback(CB const& cb) : CB(cb) {}
- void Execute() { CB::_Execute(); }
- };
-
- template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
- class Callback :
- public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > >
- {
- private:
- typedef _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > C4;
- public:
- Callback(Class *object, typename C4::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
- : _ICallback< C4 >(C4(object, method, param1, param2, param3, param4)) {}
- };
-
- template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 >
- class Callback < Class, ParamType1, ParamType2, ParamType3 > :
- public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3 > >
- {
- private:
- typedef _Callback < Class, ParamType1, ParamType2, ParamType3 > C3;
- public:
- Callback(Class *object, typename C3::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
- : _ICallback< C3 >(C3(object, method, param1, param2, param3)) {}
- };
-
- template < class Class, typename ParamType1, typename ParamType2 >
- class Callback < Class, ParamType1, ParamType2 > :
- public _ICallback< _Callback < Class, ParamType1, ParamType2 > >
- {
- private:
- typedef _Callback < Class, ParamType1, ParamType2 > C2;
- public:
- Callback(Class *object, typename C2::Method method, ParamType1 param1, ParamType2 param2)
- : _ICallback< C2 >(C2(object, method, param1, param2)) {}
- };
-
- template < class Class, typename ParamType1 >
- class Callback < Class, ParamType1 > :
- public _ICallback< _Callback < Class, ParamType1 > >
- {
- private:
- typedef _Callback < Class, ParamType1 > C1;
- public:
- Callback(Class *object, typename C1::Method method, ParamType1 param1)
- : _ICallback< C1 >(C1(object, method, param1)) {}
- };
+#ifndef _CALLBACK_H
+#define _CALLBACK_H
- template < class Class >
- class Callback < Class > : public _ICallback< _Callback < Class > >
- {
- private:
- typedef _Callback < Class > C0;
- public:
- Callback(Class *object, typename C0::Method method)
- : _ICallback< C0 >(C0(object, method)) {}
- };
-}
+#include <ace/Future.h>
+#include <ace/Future_Set.h>
-/// ---------- QUERY CALLBACKS -----------
+#include "DatabaseEnv.h"
-#include "QueryResult.h"
-class QueryResult;
+typedef ACE_Future<QueryResult_AutoPtr> QueryResultFuture;
-namespace Trinity
+/*! A simple template using ACE_Future to manage callbacks from the thread and object that
+ issued the request. <ParamType> is variable type of parameter that is used as parameter
+ for the callback function.
+*/
+template <typename ParamType>
+class QueryCallback
{
- class IQueryCallback
- {
- public:
- virtual void Execute() = 0;
- virtual ~IQueryCallback() {}
- virtual void SetResult(QueryResult_AutoPtr result) = 0;
- virtual QueryResult_AutoPtr GetResult() = 0;
- };
-
- template < class CB >
- class _IQueryCallback : public CB, public IQueryCallback
- {
- public:
- _IQueryCallback(CB const& cb) : CB(cb) {}
- void Execute() { CB::_Execute(); }
- void SetResult(QueryResult_AutoPtr result) { CB::m_param1 = result; }
- QueryResult_AutoPtr GetResult() { return CB::m_param1; }
- };
-
- template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void >
- class QueryCallback :
- public _IQueryCallback< _Callback < Class, QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3 > >
- {
- private:
- typedef _Callback < Class, QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3 > QC3;
- public:
- QueryCallback(Class *object, typename QC3::Method method, QueryResult_AutoPtr result, ParamType1 param1, ParamType2 param2, ParamType3 param3)
- : _IQueryCallback< QC3 >(QC3(object, method, result, param1, param2, param3)) {}
- };
-
- template < class Class, typename ParamType1, typename ParamType2 >
- class QueryCallback < Class, ParamType1, ParamType2 > :
- public _IQueryCallback< _Callback < Class, QueryResult_AutoPtr, ParamType1, ParamType2 > >
- {
- private:
- typedef _Callback < Class, QueryResult_AutoPtr, ParamType1, ParamType2 > QC2;
- public:
- QueryCallback(Class *object, typename QC2::Method method, QueryResult_AutoPtr result, ParamType1 param1, ParamType2 param2)
- : _IQueryCallback< QC2 >(QC2(object, method, result, param1, param2)) {}
- };
-
- template < class Class, typename ParamType1 >
- class QueryCallback < Class, ParamType1 > :
- public _IQueryCallback< _Callback < Class, QueryResult_AutoPtr, ParamType1 > >
- {
- private:
- typedef _Callback < Class, QueryResult_AutoPtr, ParamType1 > QC1;
- public:
- QueryCallback(Class *object, typename QC1::Method method, QueryResult_AutoPtr result, ParamType1 param1)
- : _IQueryCallback< QC1 >(QC1(object, method, result, param1)) {}
- };
-
- template < class Class >
- class QueryCallback < Class > : public _IQueryCallback< _Callback < Class, QueryResult_AutoPtr > >
- {
- private:
- typedef _Callback < Class, QueryResult_AutoPtr > QC0;
- public:
- QueryCallback(Class *object, typename QC0::Method method, QueryResult_AutoPtr result)
- : _IQueryCallback< QC0 >(QC0(object, method, result)) {}
- };
-
- /// ---- Statics ----
-
- template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void >
- class SQueryCallback :
- public _IQueryCallback< _SCallback < QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3 > >
- {
- private:
- typedef _SCallback < QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3 > QC3;
- public:
- SQueryCallback(typename QC3::Method method, QueryResult_AutoPtr result, ParamType1 param1, ParamType2 param2, ParamType3 param3)
- : _IQueryCallback< QC3 >(QC3(method, result, param1, param2, param3)) {}
- };
-
- template < typename ParamType1, typename ParamType2 >
- class SQueryCallback < ParamType1, ParamType2 > :
- public _IQueryCallback< _SCallback < QueryResult_AutoPtr, ParamType1, ParamType2 > >
- {
- private:
- typedef _SCallback < QueryResult_AutoPtr, ParamType1, ParamType2 > QC2;
- public:
- SQueryCallback(typename QC2::Method method, QueryResult_AutoPtr result, ParamType1 param1, ParamType2 param2)
- : _IQueryCallback< QC2 >(QC2(method, result, param1, param2)) {}
- };
-
- template < typename ParamType1 >
- class SQueryCallback < ParamType1 > :
- public _IQueryCallback< _SCallback < QueryResult_AutoPtr, ParamType1 > >
- {
- private:
- typedef _SCallback < QueryResult_AutoPtr, ParamType1 > QC1;
- public:
- SQueryCallback(typename QC1::Method method, QueryResult_AutoPtr result, ParamType1 param1)
- : _IQueryCallback< QC1 >(QC1(method, result, param1)) {}
- };
-
- template < >
- class SQueryCallback < > : public _IQueryCallback< _SCallback < QueryResult_AutoPtr > >
- {
- private:
- typedef _SCallback < QueryResult_AutoPtr > QC0;
- public:
- SQueryCallback(QC0::Method method, QueryResult_AutoPtr result)
- : _IQueryCallback< QC0 >(QC0(method, result)) {}
- };
-}
-
-#endif
-
+ public:
+ QueryCallback() {}
+
+ void SetFutureResult(QueryResultFuture value)
+ {
+ result = value;
+ }
+
+ QueryResultFuture GetFutureResult()
+ {
+ return result;
+ }
+
+ int IsReady()
+ {
+ return result.ready();
+ }
+
+ void GetResult(QueryResult_AutoPtr res)
+ {
+ result.get(res);
+ }
+
+ void FreeResult()
+ {
+ result.cancel();
+ }
+
+ void SetParam(ParamType value)
+ {
+ param = value;
+ }
+
+ ParamType GetParam()
+ {
+ return param;
+ }
+
+ private:
+ QueryResultFuture result;
+ ParamType param;
+};
+
+/*! ACE_Future_Set to store a bunch of unique async queries with callbacks.
+ (ie name queries)
+*/
+typedef ACE_Future_Set<QueryResult_AutoPtr> QueryResultFutureSet;
+#endif \ No newline at end of file
diff --git a/src/server/worldserver/WorldThread/WorldRunnable.cpp b/src/server/worldserver/WorldThread/WorldRunnable.cpp
index 555f174b6c8..7f29710c3e8 100644
--- a/src/server/worldserver/WorldThread/WorldRunnable.cpp
+++ b/src/server/worldserver/WorldThread/WorldRunnable.cpp
@@ -65,8 +65,6 @@ void WorldRunnable::run()
if (needInit)
MySQL::Thread_Init();
- sWorld.InitResultQueue();
-
uint32 realCurrTime = 0;
uint32 realPrevTime = getMSTime();