aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/DatabaseEnvFwd.h2
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.cpp2
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.h2
-rw-r--r--src/server/database/Database/QueryHolder.cpp11
-rw-r--r--src/server/database/Database/QueryHolder.h19
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp15
-rw-r--r--src/server/game/Server/WorldSession.cpp43
-rw-r--r--src/server/game/Server/WorldSession.h7
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: