diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/DatabaseEnvFwd.h | 2 | ||||
-rw-r--r-- | src/server/database/Database/DatabaseWorkerPool.cpp | 2 | ||||
-rw-r--r-- | src/server/database/Database/DatabaseWorkerPool.h | 2 | ||||
-rw-r--r-- | src/server/database/Database/QueryHolder.cpp | 11 | ||||
-rw-r--r-- | src/server/database/Database/QueryHolder.h | 19 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 15 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 43 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 7 |
8 files changed, 76 insertions, 25 deletions
diff --git a/src/server/database/Database/DatabaseEnvFwd.h b/src/server/database/Database/DatabaseEnvFwd.h index f85035cc83a..c72df398cd0 100644 --- a/src/server/database/Database/DatabaseEnvFwd.h +++ b/src/server/database/Database/DatabaseEnvFwd.h @@ -86,6 +86,8 @@ using HotfixDatabaseQueryHolder = SQLQueryHolder<HotfixDatabaseConnection>; using LoginDatabaseQueryHolder = SQLQueryHolder<LoginDatabaseConnection>; using WorldDatabaseQueryHolder = SQLQueryHolder<WorldDatabaseConnection>; +class SQLQueryHolderCallback; + // mysql struct MySQLHandle; struct MySQLResult; diff --git a/src/server/database/Database/DatabaseWorkerPool.cpp b/src/server/database/Database/DatabaseWorkerPool.cpp index 53ca065136e..facb10a5972 100644 --- a/src/server/database/Database/DatabaseWorkerPool.cpp +++ b/src/server/database/Database/DatabaseWorkerPool.cpp @@ -227,7 +227,7 @@ QueryCallback DatabaseWorkerPool<T>::AsyncQuery(PreparedStatement<T>* stmt) } template <class T> -QueryResultHolderFuture DatabaseWorkerPool<T>::DelayQueryHolder(SQLQueryHolder<T>* holder) +SQLQueryHolderCallback DatabaseWorkerPool<T>::DelayQueryHolder(SQLQueryHolder<T>* holder) { SQLQueryHolderTask* task = new SQLQueryHolderTask(holder); // Store future result before enqueueing - task might get already processed and deleted before returning from this method diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h index 13d52f99539..f46c0e29c04 100644 --- a/src/server/database/Database/DatabaseWorkerPool.h +++ b/src/server/database/Database/DatabaseWorkerPool.h @@ -160,7 +160,7 @@ class DatabaseWorkerPool //! return object as soon as the query is executed. //! The return value is then processed in ProcessQueryCallback methods. //! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag. - QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder<T>* holder); + SQLQueryHolderCallback DelayQueryHolder(SQLQueryHolder<T>* holder); /** Transaction context methods. diff --git a/src/server/database/Database/QueryHolder.cpp b/src/server/database/Database/QueryHolder.cpp index dacd12913da..eb9dbdcca22 100644 --- a/src/server/database/Database/QueryHolder.cpp +++ b/src/server/database/Database/QueryHolder.cpp @@ -92,3 +92,14 @@ bool SQLQueryHolderTask::Execute() m_result.set_value(m_holder); return true; } + +bool SQLQueryHolderCallback::InvokeIfReady() +{ + if (m_future.valid() && m_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) + { + m_callback(m_future.get()); + return true; + } + + return false; +} diff --git a/src/server/database/Database/QueryHolder.h b/src/server/database/Database/QueryHolder.h index fe4a0e78331..f94eff49d2c 100644 --- a/src/server/database/Database/QueryHolder.h +++ b/src/server/database/Database/QueryHolder.h @@ -63,4 +63,23 @@ class TC_DATABASE_API SQLQueryHolderTask : public SQLOperation QueryResultHolderFuture GetFuture() { return m_result.get_future(); } }; +class TC_DATABASE_API SQLQueryHolderCallback +{ +public: + SQLQueryHolderCallback(QueryResultHolderFuture&& future) : m_future(std::move(future)) { } + SQLQueryHolderCallback(SQLQueryHolderCallback&&) = default; + + SQLQueryHolderCallback& operator=(SQLQueryHolderCallback&&) = default; + + void AfterComplete(std::function<void(SQLQueryHolderBase*)> callback) & + { + m_callback = std::move(callback); + } + + bool InvokeIfReady(); + + QueryResultHolderFuture m_future; + std::function<void(SQLQueryHolderBase*)> m_callback; +}; + #endif diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index ef67ac1b114..befda8ece15 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -480,7 +480,10 @@ void WorldSession::HandleCharEnumOpcode(WorldPackets::Character::EnumCharacters& return; } - _charEnumCallback = CharacterDatabase.DelayQueryHolder(holder); + AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase* result) + { + HandleCharEnum(static_cast<EnumCharactersQueryHolder*>(result)); + }); } void WorldSession::HandleCharUndeleteEnumOpcode(WorldPackets::Character::EnumCharacters& /*enumCharacters*/) @@ -493,7 +496,10 @@ void WorldSession::HandleCharUndeleteEnumOpcode(WorldPackets::Character::EnumCha return; } - _charEnumCallback = CharacterDatabase.DelayQueryHolder(holder); + AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase* result) + { + HandleCharEnum(static_cast<EnumCharactersQueryHolder*>(result)); + }); } bool WorldSession::MeetsChrCustomizationReq(ChrCustomizationReqEntry const* req, Classes playerClass, @@ -1034,7 +1040,10 @@ void WorldSession::HandleContinuePlayerLogin() SendPacket(WorldPackets::Auth::ResumeComms(CONNECTION_TYPE_INSTANCE).Write()); - _charLoginCallback = CharacterDatabase.DelayQueryHolder(holder); + AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase* holder) + { + HandlePlayerLogin(static_cast<LoginQueryHolder*>(holder)); + }); } void WorldSession::AbortLogin(WorldPackets::Character::LoginFailureReason reason) diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 950b90d7214..ede413d824d 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -975,18 +975,7 @@ void WorldSession::ProcessQueryCallbacks() { _queryProcessor.ProcessReadyCallbacks(); _transactionCallbacks.ProcessReadyCallbacks(); - - if (_realmAccountLoginCallback.valid() && _realmAccountLoginCallback.wait_for(0s) == std::future_status::ready && - _accountLoginCallback.valid() && _accountLoginCallback.wait_for(0s) == std::future_status::ready) - InitializeSessionCallback(static_cast<LoginDatabaseQueryHolder*>(_realmAccountLoginCallback.get()), - static_cast<CharacterDatabaseQueryHolder*>(_accountLoginCallback.get())); - - //! HandlePlayerLoginOpcode - if (_charLoginCallback.valid() && _charLoginCallback.wait_for(0s) == std::future_status::ready) - HandlePlayerLogin(reinterpret_cast<LoginQueryHolder*>(_charLoginCallback.get())); - - if (_charEnumCallback.valid() && _charEnumCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready) - HandleCharEnum(static_cast<CharacterDatabaseQueryHolder*>(_charEnumCallback.get())); + _queryHolderProcessor.ProcessReadyCallbacks(); } TransactionCallback& WorldSession::AddTransactionCallback(TransactionCallback&& callback) @@ -994,6 +983,11 @@ TransactionCallback& WorldSession::AddTransactionCallback(TransactionCallback&& return _transactionCallbacks.AddCallback(std::move(callback)); } +SQLQueryHolderCallback& WorldSession::AddQueryHolderCallback(SQLQueryHolderCallback&& callback) +{ + return _queryHolderProcessor.AddCallback(std::move(callback)); +} + bool WorldSession::CanAccessAlliedRaces() const { return GetAccountExpansion() >= EXPANSION_BATTLE_FOR_AZEROTH; @@ -1148,11 +1142,30 @@ void WorldSession::InitializeSession() return; } - _realmAccountLoginCallback = CharacterDatabase.DelayQueryHolder(realmHolder); - _accountLoginCallback = LoginDatabase.DelayQueryHolder(holder); + struct ForkJoinState + { + AccountInfoQueryHolderPerRealm* Character = nullptr; + AccountInfoQueryHolder* Login = nullptr; + }; + + std::shared_ptr<ForkJoinState> state = std::make_shared<ForkJoinState>(); + + AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this, state](SQLQueryHolderBase* result) + { + state->Character = static_cast<AccountInfoQueryHolderPerRealm*>(result); + if (state->Login && state->Character) + InitializeSessionCallback(state->Login, state->Character); + }); + + AddQueryHolderCallback(LoginDatabase.DelayQueryHolder(holder)).AfterComplete([this, state](SQLQueryHolderBase* result) + { + state->Login = static_cast<AccountInfoQueryHolder*>(result); + if (state->Login && state->Character) + InitializeSessionCallback(state->Login, state->Character); + }); } -void WorldSession::InitializeSessionCallback(LoginDatabaseQueryHolder* realmHolder, CharacterDatabaseQueryHolder* holder) +void WorldSession::InitializeSessionCallback(LoginDatabaseQueryHolder* holder, CharacterDatabaseQueryHolder* realmHolder) { LoadAccountData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA), GLOBAL_CACHE_MASK); LoadTutorialsData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS)); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index cc3cb083263..193dea6100c 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1837,17 +1837,14 @@ class TC_GAME_API WorldSession public: QueryCallbackProcessor& GetQueryProcessor() { return _queryProcessor; } TransactionCallback& AddTransactionCallback(TransactionCallback&& callback); + SQLQueryHolderCallback& AddQueryHolderCallback(SQLQueryHolderCallback&& callback); private: void ProcessQueryCallbacks(); - QueryResultHolderFuture _realmAccountLoginCallback; - QueryResultHolderFuture _accountLoginCallback; - QueryResultHolderFuture _charLoginCallback; - QueryResultHolderFuture _charEnumCallback; - QueryCallbackProcessor _queryProcessor; AsyncCallbackProcessor<TransactionCallback> _transactionCallbacks; + AsyncCallbackProcessor<SQLQueryHolderCallback> _queryHolderProcessor; friend class World; protected: |