diff options
| author | Machiavelli <none@none> | 2010-08-18 19:48:51 +0200 |
|---|---|---|
| committer | Machiavelli <none@none> | 2010-08-18 19:48:51 +0200 |
| commit | d845a903b10b0788b03131a0cb1a2e72f55adc07 (patch) | |
| tree | 44c8e0ea6ae88217167d05203378a3324572cee5 /src/server/shared | |
| parent | 2ffe785765e3812e442d246f9561cebd83a008cb (diff) | |
DBLayer:
- 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
Diffstat (limited to 'src/server/shared')
| -rw-r--r-- | src/server/shared/Database/AsyncDatabaseImpl.h | 250 | ||||
| -rw-r--r-- | src/server/shared/Database/DatabaseWorkerPool.cpp | 26 | ||||
| -rw-r--r-- | src/server/shared/Database/DatabaseWorkerPool.h | 53 | ||||
| -rw-r--r-- | src/server/shared/Database/SQLOperation.cpp | 48 | ||||
| -rw-r--r-- | src/server/shared/Database/SQLOperation.h | 33 | ||||
| -rw-r--r-- | src/server/shared/Threading/Callback.h | 427 |
6 files changed, 122 insertions, 715 deletions
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 |
