From f6bc87fe5df8b60ca0bf3a35f61305fd780a7e7d Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 21 Jun 2015 02:13:08 +0200 Subject: Core/Threading: Fixed possible data races after making auth queries async by moving their processing to boost::asio::io_service::run threads --- src/server/game/Accounts/RBAC.cpp | 1 - src/server/game/Accounts/RBAC.h | 2 +- src/server/game/Server/WorldSocket.cpp | 27 +++++++++++++++++---------- src/server/game/Server/WorldSocket.h | 2 +- src/server/shared/Networking/Socket.h | 2 ++ 5 files changed, 21 insertions(+), 13 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp index 3f5cd6b38cf..c520564f0fa 100644 --- a/src/server/game/Accounts/RBAC.cpp +++ b/src/server/game/Accounts/RBAC.cpp @@ -17,7 +17,6 @@ #include "RBAC.h" #include "AccountMgr.h" -#include "DatabaseEnv.h" #include "Log.h" namespace rbac diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 78110d83726..db0fc711fc2 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -40,7 +40,7 @@ #ifndef _RBAC_H #define _RBAC_H -#include "Define.h" +#include "DatabaseEnv.h" #include #include #include diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 15dc782a7de..027c35dfd7f 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -77,8 +77,11 @@ void WorldSocket::Start() stmt->setString(0, ip_address); stmt->setUInt32(1, inet_addr(ip_address.c_str())); - _queryCallback = std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1); - _queryFuture = LoginDatabase.AsyncQuery(stmt); + { + std::lock_guard guard(_queryLock); + _queryCallback = io_service().wrap(std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1)); + _queryFuture = LoginDatabase.AsyncQuery(stmt); + } } void WorldSocket::CheckIpCallback(PreparedQueryResult result) @@ -124,7 +127,7 @@ bool WorldSocket::Update() return false; { - std::lock_guard lock(_queryLock); + std::lock_guard guard(_queryLock); if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { auto callback = std::move(_queryCallback); @@ -584,14 +587,17 @@ struct AccountInfo void WorldSocket::HandleAuthSession(std::shared_ptr authSession) { + // Client switches packet headers after sending CMSG_AUTH_SESSION + _headerBuffer.Resize(SizeOfClientHeader[1][1]); + // Get the account information from the auth database PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); stmt->setInt32(0, int32(realmHandle.Index)); stmt->setString(1, authSession->Account); { - std::lock_guard lock(_queryLock); - _queryCallback = std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1); + std::lock_guard guard(_queryLock); + _queryCallback = io_service().wrap(std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1)); _queryFuture = LoginDatabase.AsyncQuery(stmt); } } @@ -622,7 +628,6 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptrIsClosed()) @@ -759,7 +764,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptrInitWarden(&account.Game.SessionKey, account.BattleNet.OS); - _queryCallback = std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1); + _queryCallback = io_service().wrap(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1)); _queryFuture = _worldSession->LoadPermissionsAsync(); } @@ -781,13 +786,16 @@ void WorldSocket::HandleAuthContinuedSession(std::shared_ptrKey); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION); stmt->setUInt32(0, accountId); { - std::lock_guard lock(_queryLock); - _queryCallback = std::bind(&WorldSocket::HandleAuthContinuedSessionCallback, this, authSession, std::placeholders::_1); + std::lock_guard guard(_queryLock); + _queryCallback = io_service().wrap(std::bind(&WorldSocket::HandleAuthContinuedSessionCallback, this, authSession, std::placeholders::_1)); _queryFuture = LoginDatabase.AsyncQuery(stmt); } } @@ -808,7 +816,6 @@ void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptr _queryCallback; + std::function _queryCallback; std::string _ipCountry; }; diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h index d337e07ff52..23c4f25b742 100644 --- a/src/server/shared/Networking/Socket.h +++ b/src/server/shared/Networking/Socket.h @@ -169,6 +169,8 @@ protected: MessageBuffer _writeBuffer; #endif + boost::asio::io_service& io_service() { return _socket.get_io_service(); } + private: void ReadHandlerInternal(boost::system::error_code error, size_t transferredBytes) { -- cgit v1.2.3