summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Net/ThreadManager.cpp31
-rw-r--r--src/Net/ThreadManager.h25
-rw-r--r--src/Server/RequestHandlers/UserInfoRequestHandler.cpp30
-rw-r--r--src/Server/RequestHandlers/UserInfoRequestHandler.h6
-rw-r--r--src/Server/RequestHandlers/UserListRequestHandler.cpp39
-rw-r--r--src/Server/RequestHandlers/UserListRequestHandler.h6
-rw-r--r--src/Server/UserBackend.h15
-rw-r--r--src/Server/UserManager.cpp38
-rw-r--r--src/Server/UserManager.h23
-rw-r--r--src/modules/UserBackendMysql/UserBackendMysql.cpp46
-rw-r--r--src/modules/UserBackendMysql/UserBackendMysql.h8
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() {