diff options
-rw-r--r-- | src/Net/ThreadManager.cpp | 31 | ||||
-rw-r--r-- | src/Net/ThreadManager.h | 25 | ||||
-rw-r--r-- | src/Server/RequestHandlers/UserInfoRequestHandler.cpp | 30 | ||||
-rw-r--r-- | src/Server/RequestHandlers/UserInfoRequestHandler.h | 6 | ||||
-rw-r--r-- | src/Server/RequestHandlers/UserListRequestHandler.cpp | 39 | ||||
-rw-r--r-- | src/Server/RequestHandlers/UserListRequestHandler.h | 6 | ||||
-rw-r--r-- | src/Server/UserBackend.h | 15 | ||||
-rw-r--r-- | src/Server/UserManager.cpp | 38 | ||||
-rw-r--r-- | src/Server/UserManager.h | 23 | ||||
-rw-r--r-- | src/modules/UserBackendMysql/UserBackendMysql.cpp | 46 | ||||
-rw-r--r-- | src/modules/UserBackendMysql/UserBackendMysql.h | 8 |
11 files changed, 128 insertions, 139 deletions
diff --git a/src/Net/ThreadManager.cpp b/src/Net/ThreadManager.cpp index d24ba01..377e6e1 100644 --- a/src/Net/ThreadManager.cpp +++ b/src/Net/ThreadManager.cpp @@ -59,27 +59,27 @@ void ThreadManager::workerFunc() { } // And let the new worker thread join us... - // TODO pushWork(sigc::bind(sigc::mem_fun(this, &ThreadManager::threadFinished), (gl_thread_t)gl_thread_self())); + pushWork(boost::bind(&ThreadManager::threadFinished, this, boost::this_thread::get_id())); } void ThreadManager::detach() { - if(!isThisMainThread()) { + if(isThisMainThread()) { Common::Logger::log(Common::Logger::CRITICAL, "Tried to detach main thread! This is just WRONG!"); return; } - runLock.lock(); - bool isRunning = running; - runLock.unlock(); - if(!isRunning) // There's no point in creating a new worker thread when we aren't running anymore - return; + { + boost::lock_guard<boost::mutex> lock(runLock); + if(!running) + return; // There's no point in creating a new worker thread when we aren't running anymore + } threadLock.lock(); if(workerThread->get_id() == boost::this_thread::get_id()) {// Already detached? - threads.add_thread(workerThread); + threads.insert(std::make_pair(boost::this_thread::get_id(), workerThread)); - workerThread = new boost::thread(std::mem_fun(&ThreadManager::workerFunc), this); + workerThread.reset(new boost::thread(std::mem_fun(&ThreadManager::workerFunc), this)); } threadLock.unlock(); @@ -102,9 +102,9 @@ void ThreadManager::doInit() { ioWorker.reset(new boost::asio::io_service::work(Connection::ioService)); mainThreadId = boost::this_thread::get_id(); - workerThread = new boost::thread(&ThreadManager::workerFunc, this); - loggerThread = new boost::thread(&Common::LogManager::loggerThread, Common::LogManager::get()); - ioThread = new boost::thread((std::size_t(boost::asio::io_service::*)())&boost::asio::io_service::run, &Connection::ioService); + workerThread.reset(new boost::thread(&ThreadManager::workerFunc, this)); + loggerThread.reset(new boost::thread(&Common::LogManager::loggerThread, Common::LogManager::get())); + ioThread.reset(new boost::thread((std::size_t(boost::asio::io_service::*)())&boost::asio::io_service::run, &Connection::ioService)); threadLock.unlock(); } @@ -126,21 +126,20 @@ void ThreadManager::doDeinit() { // We don't have to lock threadLock as detach() won't change workerThread when running is false workerThread->join(); - delete workerThread; // Now wait for all detached threads - threads.join_all(); + while(!threads.empty()) { + threadFinished(threads.begin()->first); + } // IO thread is next ioWorker.reset(); Connection::ioService.stop(); ioThread->join(); - delete ioThread; // Finally, the logger thread has to die Common::LogManager::get()->stopLoggerThread(); loggerThread->join(); - delete loggerThread; } } diff --git a/src/Net/ThreadManager.h b/src/Net/ThreadManager.h index 2c57747..b8c4bec 100644 --- a/src/Net/ThreadManager.h +++ b/src/Net/ThreadManager.h @@ -25,7 +25,7 @@ #include <Common/Initializable.h> #include <queue> -#include <set> +#include <map> #include <boost/asio.hpp> @@ -39,8 +39,8 @@ namespace Net { class ThreadManager : public Common::Initializable { private: boost::thread::id mainThreadId; - boost::thread *workerThread, *loggerThread, *ioThread; - boost::thread_group threads; + boost::shared_ptr<boost::thread> workerThread, loggerThread, ioThread; + std::map<boost::thread::id, boost::shared_ptr<boost::thread> > threads; boost::mutex threadLock; @@ -60,13 +60,22 @@ class ThreadManager : public Common::Initializable { void workerFunc(); void ioFunc(); - void threadFinished(boost::thread *thread) { - threadLock.lock(); - threads.remove_thread(thread); - threadLock.unlock(); + void threadFinished(boost::thread::id threadId) { + boost::shared_ptr<boost::thread> thread; + + { + boost::lock_guard<boost::mutex> lock(threadLock); + + std::map<boost::thread::id, boost::shared_ptr<boost::thread> >::iterator it = threads.find(threadId); + + if(it == threads.end()) + return; + + thread = it->second; + threads.erase(it); + } thread->join(); - delete thread; } protected: diff --git a/src/Server/RequestHandlers/UserInfoRequestHandler.cpp b/src/Server/RequestHandlers/UserInfoRequestHandler.cpp index 740c2a9..287d026 100644 --- a/src/Server/RequestHandlers/UserInfoRequestHandler.cpp +++ b/src/Server/RequestHandlers/UserInfoRequestHandler.cpp @@ -22,8 +22,6 @@ #include <Net/Exception.h> #include <Common/Logger.h> -#include <boost/bind.hpp> - namespace Mad { namespace Server { namespace RequestHandlers { @@ -44,24 +42,22 @@ void UserInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { // TODO Require authentication - if(!UserManager::get()->getUserInfo(packet["uid"], boost::bind(&UserInfoRequestHandler::userInfoHandler, this, _1))) { - Common::XmlPacket ret; - ret.setType("Error"); - ret.add("ErrorCode", Net::Exception::NOT_IMPLEMENTED); - - sendPacket(ret); - signalFinished()(); - } -} + boost::shared_ptr<Common::UserInfo> info = UserManager::get()->getUserInfo(packet["uid"]); -void UserInfoRequestHandler::userInfoHandler(const Common::UserInfo &info) { Common::XmlPacket ret; - ret.setType("OK"); - ret.add("uid", info.getUid()); - ret.add("gid", info.getGid()); - ret.add("username", info.getUsername()); - ret.add("fullName", info.getFullName()); + if(info) { + ret.setType("OK"); + + ret.add("uid", info->getUid()); + ret.add("gid", info->getGid()); + ret.add("username", info->getUsername()); + ret.add("fullName", info->getFullName()); + } + else { + ret.setType("Error"); + ret.add("ErrorCode", Net::Exception::NOT_IMPLEMENTED); + } sendPacket(ret); signalFinished()(); diff --git a/src/Server/RequestHandlers/UserInfoRequestHandler.h b/src/Server/RequestHandlers/UserInfoRequestHandler.h index 5b1d466..90032f0 100644 --- a/src/Server/RequestHandlers/UserInfoRequestHandler.h +++ b/src/Server/RequestHandlers/UserInfoRequestHandler.h @@ -21,18 +21,12 @@ #define MAD_SERVER_REQUESTHANDLERS_USERINFOREQUESTHANDLER_H_ #include <Common/RequestHandler.h> -#include <Common/UserInfo.h> - -#include <map> namespace Mad { namespace Server { namespace RequestHandlers { class UserInfoRequestHandler : public Common::RequestHandler { - private: - void userInfoHandler(const Common::UserInfo &info); - protected: virtual void handlePacket(const Common::XmlPacket &packet); diff --git a/src/Server/RequestHandlers/UserListRequestHandler.cpp b/src/Server/RequestHandlers/UserListRequestHandler.cpp index cd05c12..713753b 100644 --- a/src/Server/RequestHandlers/UserListRequestHandler.cpp +++ b/src/Server/RequestHandlers/UserListRequestHandler.cpp @@ -22,8 +22,6 @@ #include <Net/Exception.h> #include <Common/Logger.h> -#include <boost/bind.hpp> - namespace Mad { namespace Server { namespace RequestHandlers { @@ -44,29 +42,28 @@ void UserListRequestHandler::handlePacket(const Common::XmlPacket &packet) { // TODO Require authentication - if(!UserManager::get()->getUserList(boost::bind(&UserListRequestHandler::userListHandler, this, _1))) { - Common::XmlPacket ret; - ret.setType("Error"); - ret.add("ErrorCode", Net::Exception::NOT_IMPLEMENTED); - - sendPacket(ret); - signalFinished()(); - } -} + boost::shared_ptr<std::map<unsigned long, Common::UserInfo> > info = UserManager::get()->getUserList(); -void UserListRequestHandler::userListHandler(const std::map<unsigned long, Common::UserInfo> &info) { Common::XmlPacket ret; - ret.setType("OK"); - ret.addList("users"); - for(std::map<unsigned long, Common::UserInfo>::const_iterator user = info.begin(); user != info.end(); ++user) { - ret["users"].addEntry(); - Common::XmlPacket::Entry &entry = ret["users"].back(); + if(info) { + ret.setType("OK"); + ret.addList("users"); - entry.add("uid", user->second.getUid()); - entry.add("gid", user->second.getGid()); - entry.add("username", user->second.getUsername()); - entry.add("fullName", user->second.getFullName()); + for(std::map<unsigned long, Common::UserInfo>::iterator user = info->begin(); user != info->end(); ++user) { + ret["users"].addEntry(); + Common::XmlPacket::Entry &entry = ret["users"].back(); + + entry.add("uid", user->second.getUid()); + entry.add("gid", user->second.getGid()); + entry.add("username", user->second.getUsername()); + entry.add("fullName", user->second.getFullName()); + } + } + + else { + ret.setType("Error"); + ret.add("ErrorCode", Net::Exception::NOT_IMPLEMENTED); } sendPacket(ret); diff --git a/src/Server/RequestHandlers/UserListRequestHandler.h b/src/Server/RequestHandlers/UserListRequestHandler.h index 7c85aa0..4b1a385 100644 --- a/src/Server/RequestHandlers/UserListRequestHandler.h +++ b/src/Server/RequestHandlers/UserListRequestHandler.h @@ -21,18 +21,12 @@ #define MAD_SERVER_REQUESTHANDLERS_USERLISTREQUESTHANDLER_H_ #include <Common/RequestHandler.h> -#include <Common/UserInfo.h> - -#include <map> namespace Mad { namespace Server { namespace RequestHandlers { class UserListRequestHandler : public Common::RequestHandler { - private: - void userListHandler(const std::map<unsigned long, Common::UserInfo> &info); - protected: virtual void handlePacket(const Common::XmlPacket &packet); diff --git a/src/Server/UserBackend.h b/src/Server/UserBackend.h index 6aac7bc..a673fa9 100644 --- a/src/Server/UserBackend.h +++ b/src/Server/UserBackend.h @@ -27,7 +27,7 @@ #include <map> #include <string> -#include <boost/signal.hpp> +#include <boost/smart_ptr.hpp> namespace Mad { @@ -41,19 +41,20 @@ class UserBackend { UserBackend() {} - virtual bool getUserList(const boost::function1<void, const std::map<unsigned long, Common::UserInfo>& > &callback _UNUSED_PARAMETER_) { - return false; + virtual boost::shared_ptr<std::map<unsigned long, Common::UserInfo> > getUserList() { + return boost::shared_ptr<std::map<unsigned long, Common::UserInfo> >(); } - virtual bool getUserInfo(unsigned long uid _UNUSED_PARAMETER_, const boost::function1<void, const Common::UserInfo&> &callback _UNUSED_PARAMETER_) { - return false; + virtual boost::shared_ptr<Common::UserInfo> getUserInfo(unsigned long uid _UNUSED_PARAMETER_) { + return boost::shared_ptr<Common::UserInfo>(); } - virtual bool setPassword(unsigned long uid _UNUSED_PARAMETER_, const std::string&, const boost::function1<void, bool> &callback _UNUSED_PARAMETER_) { + // TODO Better interface... + virtual bool setPassword(unsigned long uid _UNUSED_PARAMETER_, const std::string &password _UNUSED_PARAMETER_) { return false; } - virtual bool addUser(const Common::UserInfo &userInfo _UNUSED_PARAMETER_, const boost::function1<void, bool> &callback _UNUSED_PARAMETER_) { + virtual bool addUser(const Common::UserInfo &userInfo _UNUSED_PARAMETER_) { return false; } diff --git a/src/Server/UserManager.cpp b/src/Server/UserManager.cpp index d763a8b..3b5887a 100644 --- a/src/Server/UserManager.cpp +++ b/src/Server/UserManager.cpp @@ -26,44 +26,46 @@ namespace Server { UserManager UserManager::userManager; -bool UserManager::Compare::operator() (const UserBackend *b1, const UserBackend *b2) { +bool UserManager::Compare::operator() (boost::shared_ptr<UserBackend> b1, boost::shared_ptr<UserBackend> b2) { if(b1->getPriority() == b2->getPriority()) - return (b1 > b2); + return (b1.get() > b2.get()); else return (b1->getPriority() > b2->getPriority()); } -bool UserManager::getUserList(const boost::function1<void, const std::map<unsigned long, Common::UserInfo>& > &callback) { - for(std::set<UserBackend*>::iterator backend = backends.begin(); backend != backends.end(); ++backend) { - if((*backend)->getUserList(callback)) - return true; +boost::shared_ptr<std::map<unsigned long, Common::UserInfo> > UserManager::getUserList() { + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + boost::shared_ptr<std::map<unsigned long, Common::UserInfo> > ret = (*backend)->getUserList(); + if(ret) + return ret; } - return false; + return boost::shared_ptr<std::map<unsigned long, Common::UserInfo> >(); } -bool UserManager::getUserInfo(unsigned long uid, const boost::function1<void, const Common::UserInfo&> &callback) { - for(std::set<UserBackend*>::iterator backend = backends.begin(); backend != backends.end(); ++backend) { - if((*backend)->getUserInfo(uid, callback)) - return true; +boost::shared_ptr<Common::UserInfo> UserManager::getUserInfo(unsigned long uid) { + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + boost::shared_ptr<Common::UserInfo> ret = (*backend)->getUserInfo(uid); + if(ret) + return ret; } - return false; + return boost::shared_ptr<Common::UserInfo>(); } -bool UserManager::setPassword(unsigned long uid, const std::string &password, const boost::function1<void, bool> &callback) { - for(std::set<UserBackend*>::iterator backend = backends.begin(); backend != backends.end(); ++backend) { - if((*backend)->setPassword(uid, password, callback)) +bool UserManager::setPassword(unsigned long uid, const std::string &password) { + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + if((*backend)->setPassword(uid, password)) return true; } return false; } -bool UserManager::addUser(const Common::UserInfo &userInfo, const boost::function1<void, bool> &callback) { - for(std::set<UserBackend*>::iterator backend = backends.begin(); backend != backends.end(); ++backend) { - if((*backend)->addUser(userInfo, callback)) +bool UserManager::addUser(const Common::UserInfo &userInfo) { + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + if((*backend)->addUser(userInfo)) return true; } diff --git a/src/Server/UserManager.h b/src/Server/UserManager.h index d0e7074..c3d990d 100644 --- a/src/Server/UserManager.h +++ b/src/Server/UserManager.h @@ -25,42 +25,41 @@ #include <map> #include <set> -#include <boost/function.hpp> +#include <boost/smart_ptr.hpp> +#include <boost/noncopyable.hpp> namespace Mad { namespace Server { class UserBackend; -class UserManager { +class UserManager : boost::noncopyable { private: struct Compare { - bool operator() (const UserBackend *b1, const UserBackend *b2); + bool operator() (boost::shared_ptr<UserBackend> b1, boost::shared_ptr<UserBackend> b2); }; static UserManager userManager; - std::set<UserBackend*, Compare> backends; + std::set<boost::shared_ptr<UserBackend>, Compare> backends; UserManager() {} public: - void registerBackend(UserBackend *backend) { + void registerBackend(boost::shared_ptr<UserBackend> backend) { backends.insert(backend); } - void unregisterBackend(UserBackend *backend) { + void unregisterBackend(boost::shared_ptr<UserBackend> backend) { backends.erase(backend); } + boost::shared_ptr<std::map<unsigned long, Common::UserInfo> > getUserList(); + boost::shared_ptr<Common::UserInfo> getUserInfo(unsigned long uid); - bool getUserList(const boost::function1<void, const std::map<unsigned long, Common::UserInfo>& > &callback); - bool getUserInfo(unsigned long uid, const boost::function1<void, const Common::UserInfo&> &callback); - - bool setPassword(unsigned long uid, const std::string &password, const boost::function1<void, bool> &callback); - - bool addUser(const Common::UserInfo &userInfo, const boost::function1<void, bool> &callback); + bool setPassword(unsigned long uid, const std::string &password); + bool addUser(const Common::UserInfo &userInfo); static UserManager *get() { return &userManager; diff --git a/src/modules/UserBackendMysql/UserBackendMysql.cpp b/src/modules/UserBackendMysql/UserBackendMysql.cpp index ebea4dc..a8751ee 100644 --- a/src/modules/UserBackendMysql/UserBackendMysql.cpp +++ b/src/modules/UserBackendMysql/UserBackendMysql.cpp @@ -34,7 +34,7 @@ namespace Mad { namespace Modules { -UserBackendMysql *UserBackendMysql::backend; +boost::shared_ptr<UserBackendMysql> UserBackendMysql::backend; bool UserBackendMysql::handleConfigEntry(const Common::ConfigEntry &entry, bool handled) { if(handled) @@ -132,16 +132,18 @@ void UserBackendMysql::configFinished() { } -bool UserBackendMysql::getUserList(const boost::function1<void, const std::map<unsigned long, Common::UserInfo>& > &callback) { +boost::shared_ptr<std::map<unsigned long, Common::UserInfo> > UserBackendMysql::getUserList() { + Net::ThreadManager::get()->detach(); + mysql_ping(mysql); mysql_real_query(mysql, queryListUsers.c_str(), queryListUsers.length()); MYSQL_RES *result = mysql_use_result(mysql); if(mysql_num_fields(result) < 4) - return true; // TODO Error + return boost::shared_ptr<std::map<unsigned long, Common::UserInfo> >(); // TODO Error - std::map<unsigned long, Common::UserInfo> users; + boost::shared_ptr<std::map<unsigned long, Common::UserInfo> > users(new std::map<unsigned long, Common::UserInfo>()); while(MYSQL_ROW row = mysql_fetch_row(result)) { Common::UserInfo user(strtoul(row[0], 0, 10), row[2]); @@ -149,15 +151,15 @@ bool UserBackendMysql::getUserList(const boost::function1<void, const std::map<u user.setGid(strtoul(row[1], 0, 10)); user.setFullName(row[3]); - users.insert(std::make_pair(user.getUid(), user)); + users->insert(std::make_pair(user.getUid(), user)); } - Net::ThreadManager::get()->pushWork(boost::bind(callback, users)); - - return true; + return users; } -bool UserBackendMysql::getUserInfo(unsigned long uid, const boost::function1<void, const Common::UserInfo&> &callback) { +boost::shared_ptr<Common::UserInfo> UserBackendMysql::getUserInfo(unsigned long uid) { + Net::ThreadManager::get()->detach(); + mysql_ping(mysql); std::string query = queryUserById; @@ -173,25 +175,22 @@ bool UserBackendMysql::getUserInfo(unsigned long uid, const boost::function1<voi MYSQL_RES *result = mysql_use_result(mysql); if(mysql_num_fields(result) < 4) - return true; // TODO Error + return boost::shared_ptr<Common::UserInfo>(); // TODO Error MYSQL_ROW row = mysql_fetch_row(result); if(row) { - Common::UserInfo user(strtoul(row[0], 0, 10), row[2]); + boost::shared_ptr<Common::UserInfo> user(new Common::UserInfo(strtoul(row[0], 0, 10), row[2])); - user.setGid(strtoul(row[1], 0, 10)); - user.setFullName(row[3]); - - Net::ThreadManager::get()->pushWork(boost::bind(callback, user)); + user->setGid(strtoul(row[1], 0, 10)); + user->setFullName(row[3]); while((row = mysql_fetch_row(result)) != 0) {} - } - else { - Net::ThreadManager::get()->pushWork(boost::bind(callback, Common::UserInfo())); + + return user; } - return true; + return boost::shared_ptr<Common::UserInfo>(); } @@ -199,19 +198,18 @@ void UserBackendMysql::registerBackend() { if(backend) return; - backend = new UserBackendMysql(); - Common::ConfigManager::get()->registerConfigurable(backend); + backend.reset(new UserBackendMysql()); + Common::ConfigManager::get()->registerConfigurable(backend.get()); } void UserBackendMysql::unregisterBackend() { if(!backend) return; - Common::ConfigManager::get()->unregisterConfigurable(backend); + Common::ConfigManager::get()->unregisterConfigurable(backend.get()); Server::UserManager::get()->unregisterBackend(backend); - delete backend; - backend = 0; + backend.reset(); } } diff --git a/src/modules/UserBackendMysql/UserBackendMysql.h b/src/modules/UserBackendMysql/UserBackendMysql.h index 2e4f1ff..de28069 100644 --- a/src/modules/UserBackendMysql/UserBackendMysql.h +++ b/src/modules/UserBackendMysql/UserBackendMysql.h @@ -30,9 +30,9 @@ namespace Mad { namespace Modules { -class UserBackendMysql : private Server::UserBackend, private Common::Configurable { +class UserBackendMysql : public Server::UserBackend, private Common::Configurable { private: - static UserBackendMysql *backend; + static boost::shared_ptr<UserBackendMysql> backend; std::string host, username, passwd, db, unixSocket; uint16_t port; @@ -50,8 +50,8 @@ class UserBackendMysql : private Server::UserBackend, private Common::Configurab virtual bool handleConfigEntry(const Common::ConfigEntry &entry, bool); virtual void configFinished(); - virtual bool getUserList(const boost::function1<void, const std::map<unsigned long, Common::UserInfo>& > &callback); - virtual bool getUserInfo(unsigned long uid, const boost::function1<void, const Common::UserInfo&> &callback); + virtual boost::shared_ptr<std::map<unsigned long, Common::UserInfo> > getUserList(); + virtual boost::shared_ptr<Common::UserInfo> getUserInfo(unsigned long uid); public: virtual ~UserBackendMysql() { |