summaryrefslogtreecommitdiffstats
path: root/src/Common
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-06-04 22:23:07 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-06-04 22:23:07 +0200
commit0b27c37fe95c6aced613d51a3624f8930a96ad3f (patch)
tree5cb92568f70fe9789e99633ec71048389efb7fa4 /src/Common
parent50d92f64547c5c06851976ceab5ed631ec93f647 (diff)
downloadmad-0b27c37fe95c6aced613d51a3624f8930a96ad3f.tar
mad-0b27c37fe95c6aced613d51a3624f8930a96ad3f.zip
RequestHandler-Interface ?berarbeitet
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/CMakeLists.txt4
-rw-r--r--src/Common/Connection.cpp2
-rw-r--r--src/Common/Connection.h8
-rw-r--r--src/Common/Request.cpp14
-rw-r--r--src/Common/Request.h87
-rw-r--r--src/Common/RequestHandler.cpp40
-rw-r--r--src/Common/RequestHandler.h47
-rw-r--r--src/Common/RequestHandlers/DisconnectRequestHandler.cpp4
-rw-r--r--src/Common/RequestHandlers/DisconnectRequestHandler.h6
-rw-r--r--src/Common/RequestHandlers/FSInfoRequestHandler.cpp4
-rw-r--r--src/Common/RequestHandlers/FSInfoRequestHandler.h6
-rw-r--r--src/Common/RequestHandlers/StatusRequestHandler.cpp4
-rw-r--r--src/Common/RequestHandlers/StatusRequestHandler.h6
-rw-r--r--src/Common/RequestManager.cpp117
-rw-r--r--src/Common/RequestManager.h158
-rw-r--r--src/Common/Requests/DisconnectRequest.cpp12
-rw-r--r--src/Common/Requests/DisconnectRequest.h6
-rw-r--r--src/Common/Requests/FSInfoRequest.h3
-rw-r--r--src/Common/Requests/GroupListRequest.h3
-rw-r--r--src/Common/Requests/GroupUserListRequest.h3
-rw-r--r--src/Common/Requests/IdentifyRequest.h3
-rw-r--r--src/Common/Requests/SimpleRequest.h3
-rw-r--r--src/Common/Requests/StatusRequest.h3
-rw-r--r--src/Common/Requests/UserGroupListRequest.h3
-rw-r--r--src/Common/Requests/UserInfoRequest.h4
-rw-r--r--src/Common/Requests/UserListRequest.h3
26 files changed, 260 insertions, 293 deletions
diff --git a/src/Common/CMakeLists.txt b/src/Common/CMakeLists.txt
index fe18760..de6dfc7 100644
--- a/src/Common/CMakeLists.txt
+++ b/src/Common/CMakeLists.txt
@@ -8,7 +8,7 @@ link_directories(${LTDL_LIBRARY_DIR})
add_library(Common
Base64Encoder.cpp ClientConnection.cpp ConfigEntry.cpp
ConfigManager.cpp Connection.cpp Initializable.cpp Logger.cpp LogManager.cpp
- ModuleManager.cpp Request.cpp RequestManager.cpp SystemManager.cpp Tokenizer.cpp
- XmlPacket.cpp
+ ModuleManager.cpp Request.cpp RequestHandler.cpp RequestManager.cpp SystemManager.cpp
+ Tokenizer.cpp XmlPacket.cpp
)
target_link_libraries(Common RequestHandlers Requests Net ${LIBXML2_LIBRARIES} ${LTDL_LIBRARIES})
diff --git a/src/Common/Connection.cpp b/src/Common/Connection.cpp
index db962ea..6afd5f0 100644
--- a/src/Common/Connection.cpp
+++ b/src/Common/Connection.cpp
@@ -24,7 +24,7 @@ namespace Mad {
namespace Common {
void Connection::receive(boost::shared_ptr<Net::Packet> packet) {
- signalReceive.emit(XmlPacket(*packet), packet->getRequestId());
+ signalReceive.emit(boost::shared_ptr<XmlPacket>(new XmlPacket(*packet)), packet->getRequestId());
}
bool Connection::sendPacket(const XmlPacket &packet, uint16_t requestId) {
diff --git a/src/Common/Connection.h b/src/Common/Connection.h
index b794a88..6f1cffd 100644
--- a/src/Common/Connection.h
+++ b/src/Common/Connection.h
@@ -39,7 +39,7 @@ class Connection : private boost::noncopyable {
private:
bool authenticated;
- Net::Signals::Signal2<const XmlPacket&, uint16_t> signalReceive;
+ Net::Signals::Signal22<boost::shared_ptr<const XmlPacket>, uint16_t> signalReceive;
protected:
Connection() : authenticated(0) {}
@@ -53,9 +53,13 @@ class Connection : private boost::noncopyable {
bool sendPacket(const XmlPacket &packet, uint16_t requestId);
- Net::Signals::Connection connectSignalReceive(const Net::Signals::Signal2<const XmlPacket&, uint16_t>::slot_type &slot) {
+ Net::Signals::Connection2 connectSignalReceive(const Net::Signals::Signal22<boost::shared_ptr<const XmlPacket>, uint16_t>::slot_type &slot) {
return signalReceive.connect(slot);
}
+ void disconnectSignalReceive(const Net::Signals::Connection2 &con) {
+ signalReceive.disconnect(con);
+ }
+
virtual bool disconnect() = 0;
//virtual void* getCertificate(size_t *size) const = 0;
diff --git a/src/Common/Request.cpp b/src/Common/Request.cpp
index e27c1b9..723039f 100644
--- a/src/Common/Request.cpp
+++ b/src/Common/Request.cpp
@@ -22,19 +22,17 @@
namespace Mad {
namespace Common {
-Request::slot_type Request::empty_slot(&Request::doNothing);
-
-void Request::handlePacket(const XmlPacket &packet) {
- if(packet.getType() == "Error") {
- finishWithError(Net::Exception(packet["Where"], packet["ErrorCode"], packet["SubCode"], packet["SubSubCode"]));
+void Request::handlePacket(boost::shared_ptr<const XmlPacket> packet) {
+ if(packet->getType() == "Error") {
+ signalFinished(Net::Exception((*packet)["Where"], (*packet)["ErrorCode"], (*packet)["SubCode"], (*packet)["SubSubCode"]));
return;
}
- else if(packet.getType() != "OK") {
- finishWithError(Net::Exception(Net::Exception::UNEXPECTED_PACKET));
+ else if(packet->getType() != "OK") {
+ signalFinished(Net::Exception(Net::Exception::UNEXPECTED_PACKET));
return; // TODO Logging
}
- finish(packet);
+ signalFinished(packet);
}
}
diff --git a/src/Common/Request.h b/src/Common/Request.h
index d351c2a..b8477f7 100644
--- a/src/Common/Request.h
+++ b/src/Common/Request.h
@@ -17,8 +17,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MAD_COMMON_XMLREQUEST_H_
-#define MAD_COMMON_XMLREQUEST_H_
+#ifndef MAD_COMMON_REQUEST_H_
+#define MAD_COMMON_REQUEST_H_
#include "RequestHandler.h"
#include <Net/Exception.h>
@@ -37,80 +37,54 @@ class Request : public RequestHandler {
private:
friend class RequestManager;
- Net::Signals::Signal1<Request&> finished;
-
- std::auto_ptr<XmlPacket> res;
- Net::Exception exp;
-
boost::mutex mutex;
boost::condition_variable finishCond;
bool isFinished;
- static void doNothing(Request&) {}
+ boost::shared_ptr<const XmlPacket> packet;
+ Net::Exception exception;
- public:
- typedef Net::Signals::Signal1<Request&>::slot_type slot_type;
+ Net::Signals::Signal22<boost::shared_ptr<const XmlPacket>, Net::Exception> finished;
protected:
- static slot_type empty_slot;
-
- Request(Connection *connection, uint16_t requestId, slot_type slot)
- : RequestHandler(connection, requestId), exp(Net::Exception::NOT_FINISHED), isFinished(false) {
- finished.connect(slot);
- finished.connect(boost::bind(&Request::signalFinished, this));
- }
-
- virtual ~Request() {
- wait();
- }
+ Request() : isFinished(false) {}
- void finish(std::auto_ptr<XmlPacket> result) {
+ void signalFinished(boost::shared_ptr<const XmlPacket> pkt, Net::Exception exp) {
{
boost::lock_guard<boost::mutex> lock(mutex);
- res = result;
isFinished = true;
+ packet = pkt;
+ exception = exp;
}
+ finished.emit(pkt, exp);
finishCond.notify_all();
- finished.emit(*this);
- }
- void finish(const XmlPacket& result) {
- {
- boost::lock_guard<boost::mutex> lock(mutex);
-
- res.reset(new XmlPacket(result));
- isFinished = true;
- }
-
- finishCond.notify_all();
- finished.emit(*this);
+ RequestHandler::signalFinished();
}
- void finishWithError(const Net::Exception &e) {
- {
- boost::lock_guard<boost::mutex> lock(mutex);
+ void signalFinished(boost::shared_ptr<const XmlPacket> packet) {
+ signalFinished(packet, Net::Exception());
+ }
- exp = e;
- isFinished = true;
- }
+ void signalFinished(Net::Exception exp) {
+ signalFinished(boost::shared_ptr<const XmlPacket>(), exp);
+ }
- finishCond.notify_all();
- finished.emit(*this);
+ void signalFinished() {
+ signalFinished(boost::shared_ptr<const XmlPacket>(), Net::Exception());
}
virtual void sendRequest() = 0;
- virtual void handlePacket(const XmlPacket &packet);
+ virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet);
public:
- const XmlPacket& getResult() throw(Net::Exception) {
- boost::lock_guard<boost::mutex> lock(mutex);
-
- if(res.get())
- return *res;
-
- throw exp;
+ Net::Signals::Connection2 connectSignalFinished(const Net::Signals::Signal22<boost::shared_ptr<const XmlPacket>, Net::Exception>::slot_type &slot) {
+ return finished.connect(slot);
+ }
+ void disconnectSignalFinished(const Net::Signals::Connection2 &con) {
+ finished.disconnect(con);
}
void wait() {
@@ -119,9 +93,18 @@ class Request : public RequestHandler {
while(!isFinished)
finishCond.wait(lock);
}
+
+ std::pair<boost::shared_ptr<const XmlPacket>, Net::Exception> getResult() {
+ boost::lock_guard<boost::mutex> lock(mutex);
+
+ if(!isFinished)
+ return std::make_pair(boost::shared_ptr<const XmlPacket>(), Net::Exception(Net::Exception::NOT_FINISHED));
+ else
+ return std::make_pair(packet, exception);
+ }
};
}
}
-#endif /* MAD_COMMON_XMLREQUEST_H_ */
+#endif /* MAD_COMMON_REQUEST_H_ */
diff --git a/src/Common/RequestHandler.cpp b/src/Common/RequestHandler.cpp
new file mode 100644
index 0000000..218155d
--- /dev/null
+++ b/src/Common/RequestHandler.cpp
@@ -0,0 +1,40 @@
+/*
+ * RequestHandler.cpp
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "RequestHandler.h"
+#include "RequestManager.h"
+
+namespace Mad {
+namespace Common {
+
+Connection* RequestHandler::getConnection() const {
+ return RequestManager::get()->requestMap.getRequestInfo(this).first;
+}
+
+void RequestHandler::sendPacket(const XmlPacket &packet) {
+ std::pair<Connection*, boost::uint16_t> requestInfo = RequestManager::get()->requestMap.getRequestInfo(this);
+
+ if(!requestInfo.first)
+ return;
+
+ requestInfo.first->sendPacket(packet, requestInfo.second);
+}
+
+}
+}
diff --git a/src/Common/RequestHandler.h b/src/Common/RequestHandler.h
index d35ab1b..87fccba 100644
--- a/src/Common/RequestHandler.h
+++ b/src/Common/RequestHandler.h
@@ -17,8 +17,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MAD_COMMON_XMLREQUESTHANDLER_H_
-#define MAD_COMMON_XMLREQUESTHANDLER_H_
+#ifndef MAD_COMMON_REQUESTHANDLER_H_
+#define MAD_COMMON_REQUESTHANDLER_H_
#include "Connection.h"
#include "XmlPacket.h"
@@ -26,6 +26,8 @@
#include <Net/Signals/Signals.h>
#include <boost/cstdint.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
namespace Mad {
namespace Common {
@@ -35,43 +37,42 @@ class RequestManager;
class RequestHandler : private boost::noncopyable {
private:
- Net::Signals::Signal0 finished;
+ friend class RequestManager;
- Connection *connection;
- boost::uint16_t requestId;
+ boost::mutex mutex;
- protected:
- RequestHandler(Connection *connection0, boost::uint16_t requestId0) : connection(connection0), requestId(requestId0) {}
+ Net::Signals::Signal20 finished;
- void signalFinished() {
- finished.emit();
+ void callHandlePacket(boost::shared_ptr<const XmlPacket> packet) {
+ boost::lock_guard<boost::mutex> lock(mutex);
+ handlePacket(packet);
}
- Net::Signals::Connection connectSignalFinished(const Net::Signals::Signal0::slot_type &slot) {
- return finished.connect(slot);
- }
+ protected:
+ RequestHandler() {}
- Connection* getConnection() const {
- return connection;
+ void signalFinished() {
+ finished.emit();
}
- boost::uint16_t getRequestId() const {
- return requestId;
- }
+ Connection* getConnection() const;
- void sendPacket(const XmlPacket &packet) {
- connection->sendPacket(packet, requestId);
- }
+ void sendPacket(const XmlPacket &packet);
- virtual void handlePacket(const XmlPacket &packet) = 0;
+ virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet) = 0;
public:
virtual ~RequestHandler() {}
- friend class RequestManager;
+ Net::Signals::Connection2 connectSignalFinished(const Net::Signals::Signal20::slot_type &slot) {
+ return finished.connect(slot);
+ }
+ void disconnectSignalFinished(const Net::Signals::Connection2 &con) {
+ finished.disconnect(con);
+ }
};
}
}
-#endif /* MAD_COMMON_XMLREQUESTHANDLER_H_ */
+#endif /* MAD_COMMON_REQUESTHANDLER_H_ */
diff --git a/src/Common/RequestHandlers/DisconnectRequestHandler.cpp b/src/Common/RequestHandlers/DisconnectRequestHandler.cpp
index ac8e7dc..942da0a 100644
--- a/src/Common/RequestHandlers/DisconnectRequestHandler.cpp
+++ b/src/Common/RequestHandlers/DisconnectRequestHandler.cpp
@@ -25,8 +25,8 @@ namespace Mad {
namespace Common {
namespace RequestHandlers {
-void DisconnectRequestHandler::handlePacket(const XmlPacket &packet) {
- if(packet.getType() != "Disconnect") {
+void DisconnectRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> packet) {
+ if(packet->getType() != "Disconnect") {
Logger::log(Logger::ERROR, "Received an unexpected packet.");
XmlPacket ret;
diff --git a/src/Common/RequestHandlers/DisconnectRequestHandler.h b/src/Common/RequestHandlers/DisconnectRequestHandler.h
index 05b9c50..963f603 100644
--- a/src/Common/RequestHandlers/DisconnectRequestHandler.h
+++ b/src/Common/RequestHandlers/DisconnectRequestHandler.h
@@ -28,11 +28,7 @@ namespace RequestHandlers {
class DisconnectRequestHandler : public RequestHandler {
protected:
- virtual void handlePacket(const XmlPacket &packet);
-
- public:
- DisconnectRequestHandler(Connection *connection, uint16_t requestId)
- : RequestHandler(connection, requestId) {}
+ virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet);
};
}
diff --git a/src/Common/RequestHandlers/FSInfoRequestHandler.cpp b/src/Common/RequestHandlers/FSInfoRequestHandler.cpp
index 9044c68..845258b 100644
--- a/src/Common/RequestHandlers/FSInfoRequestHandler.cpp
+++ b/src/Common/RequestHandlers/FSInfoRequestHandler.cpp
@@ -27,8 +27,8 @@ namespace Mad {
namespace Common {
namespace RequestHandlers {
-void FSInfoRequestHandler::handlePacket(const XmlPacket &packet) {
- if(packet.getType() != "FSInfo") {
+void FSInfoRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> packet) {
+ if(packet->getType() != "FSInfo") {
Logger::log(Logger::ERROR, "Received an unexpected packet.");
XmlPacket ret;
diff --git a/src/Common/RequestHandlers/FSInfoRequestHandler.h b/src/Common/RequestHandlers/FSInfoRequestHandler.h
index 47fcbd8..6d21787 100644
--- a/src/Common/RequestHandlers/FSInfoRequestHandler.h
+++ b/src/Common/RequestHandlers/FSInfoRequestHandler.h
@@ -31,11 +31,7 @@ namespace RequestHandlers {
class FSInfoRequestHandler : public RequestHandler {
protected:
- virtual void handlePacket(const XmlPacket &packet);
-
- public:
- FSInfoRequestHandler(Connection *connection, uint16_t requestId)
- : RequestHandler(connection, requestId) {}
+ virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet);
};
}
diff --git a/src/Common/RequestHandlers/StatusRequestHandler.cpp b/src/Common/RequestHandlers/StatusRequestHandler.cpp
index e766670..989ce7c 100644
--- a/src/Common/RequestHandlers/StatusRequestHandler.cpp
+++ b/src/Common/RequestHandlers/StatusRequestHandler.cpp
@@ -28,8 +28,8 @@ namespace Mad {
namespace Common {
namespace RequestHandlers {
-void StatusRequestHandler::handlePacket(const XmlPacket &packet) {
- if(packet.getType() != "GetStatus") {
+void StatusRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> packet) {
+ if(packet->getType() != "GetStatus") {
Logger::log(Logger::ERROR, "Received an unexpected packet.");
XmlPacket ret;
diff --git a/src/Common/RequestHandlers/StatusRequestHandler.h b/src/Common/RequestHandlers/StatusRequestHandler.h
index 151852c..656a1a5 100644
--- a/src/Common/RequestHandlers/StatusRequestHandler.h
+++ b/src/Common/RequestHandlers/StatusRequestHandler.h
@@ -29,11 +29,7 @@ namespace RequestHandlers {
class StatusRequestHandler : public RequestHandler {
protected:
- virtual void handlePacket(const XmlPacket &packet);
-
- public:
- StatusRequestHandler(Connection *connection, uint16_t requestId)
- : RequestHandler(connection, requestId) {}
+ virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet);
};
}
diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp
index da9979a..3817ff5 100644
--- a/src/Common/RequestManager.cpp
+++ b/src/Common/RequestManager.cpp
@@ -29,71 +29,105 @@ namespace Common {
RequestManager RequestManager::requestManager;
-bool RequestManager::RequestMap::addRequest(boost::uint16_t id, boost::shared_ptr<RequestHandler> info) {
- if(!insert(std::make_pair(id, info)).second)
+void RequestManager::RequestMap::unregisterConnection(Connection *connection) {
+ std::map<Connection*, IdMap>::iterator idMap = connectionMap.find(connection);
+ if(idMap == connectionMap.end())
+ return;
+
+ for(IdMap::iterator request = idMap->second.begin(); request != idMap->second.end(); ++request)
+ handlerMap.erase(request->second.get());
+
+ connectionMap.erase(idMap);
+}
+
+bool RequestManager::RequestMap::addRequest(Connection *con, boost::uint16_t id, boost::shared_ptr<RequestHandler> request) {
+ std::map<Connection*, IdMap>::iterator idMap = connectionMap.find(con);
+ if(idMap == connectionMap.end())
+ return false;
+
+ if(!idMap->second.insert(std::make_pair(id, request)).second)
return false;
- info->connectSignalFinished(boost::bind(&RequestManager::RequestMap::deleteRequest, this, id));
+ if(!handlerMap.insert(std::make_pair(request.get(), std::make_pair(con, id))).second) {
+ idMap->second.erase(id);
+ return false;
+ }
return true;
}
-boost::shared_ptr<RequestHandler> RequestManager::RequestMap::findRequest(boost::uint16_t id) {
- iterator it = find(id);
- if(it == end())
+boost::shared_ptr<RequestHandler> RequestManager::RequestMap::findRequest(Connection *con, boost::uint16_t id) {
+ std::map<Connection*, IdMap>::iterator idMap = connectionMap.find(con);
+ if(idMap == connectionMap.end())
+ return boost::shared_ptr<RequestHandler>();
+
+ IdMap::iterator it = idMap->second.find(id);
+ if(it == idMap->second.end())
return boost::shared_ptr<RequestHandler>();
return it->second;
}
-void RequestManager::RequestMap::deleteRequest(boost::uint16_t id) {
- Net::ThreadManager::get()->pushWork(boost::bind(&RequestMap::doDeleteRequest, this, id));
+void RequestManager::RequestMap::deleteRequest(Connection *con, boost::uint16_t id) {
+ std::map<Connection*, IdMap>::iterator idMap = connectionMap.find(con);
+ if(idMap == connectionMap.end())
+ return;
+
+ IdMap::iterator it = idMap->second.find(id);
+ if(it == idMap->second.end())
+ return;
+
+ handlerMap.erase(it->second.get());
+ idMap->second.erase(it);
}
-void RequestManager::RequestMap::doDeleteRequest(boost::uint16_t id) {
- erase(id);
+std::pair<Connection*, boost::uint16_t> RequestManager::RequestMap::getRequestInfo(const RequestHandler *requestHandler) {
+ HandlerMap::iterator it = handlerMap.find(requestHandler);
+ if(it == handlerMap.end())
+ return std::pair<Connection*, boost::uint16_t>(0, 0);
+ else
+ return it->second;
}
-void RequestManager::receiveHandler(Connection *connection, const XmlPacket &packet, boost::uint16_t requestId) {
+void RequestManager::receiveHandler(Connection *connection, boost::shared_ptr<const XmlPacket> packet, boost::uint16_t requestId) {
boost::upgrade_lock<boost::shared_mutex> lock(mutex);
- std::map<Connection*, boost::shared_ptr<RequestMap> >::iterator it = requestMaps.find(connection);
- if(it == requestMaps.end()) {
- // TODO: Error
- Logger::log(Logger::ERROR, "Received a packet from an unregistered connection.");
+ boost::shared_ptr<RequestHandler> request = requestMap.findRequest(connection, requestId);
+ if(request) {
+ lock.unlock();
+ request->callHandlePacket(packet);
return;
}
- boost::shared_ptr<RequestMap> requestMap = it->second;
- boost::shared_ptr<RequestHandler> request = requestMap->findRequest(requestId);
-
- if(request) {
- lock.unlock();
- request->handlePacket(packet);
+ if(!requestMap.isConnectionRegistered(connection)) {
+ // TODO: Error
+ Logger::log(Logger::ERROR, "Received a packet from an unregistered connection.");
return;
}
- std::map<std::string, boost::shared_ptr<RequestHandlerFactory> >::iterator factoryIt = requestHandlerFactories.find(packet.getType());
+ std::map<std::string, boost::shared_ptr<RequestHandlerFactory> >::iterator factoryIt = requestHandlerFactories.find(packet->getType());
if(factoryIt != requestHandlerFactories.end()) {
{
boost::upgrade_to_unique_lock<boost::shared_mutex> upgradeLock(lock);
- request = factoryIt->second->createRequestHandler(connection, requestId);
- requestMap->addRequest(requestId, request);
+ request = factoryIt->second->createRequestHandler();
+ requestMap.addRequest(connection, requestId, request);
+ request->connectSignalFinished(boost::bind(&RequestManager::handleRequestFinished, this, connection, requestId));
+
}
lock.unlock();
- request->handlePacket(packet);
+ request->callHandlePacket(packet);
return;
}
lock.unlock();
- Logger::logf(Logger::ERROR, "Received an unexpected packet with type '%s'.", packet.getType().c_str());
+ Logger::logf(Logger::ERROR, "Received an unexpected packet with type '%s'.", packet->getType().c_str());
XmlPacket ret;
ret.setType("Error");
@@ -102,28 +136,37 @@ void RequestManager::receiveHandler(Connection *connection, const XmlPacket &pac
connection->sendPacket(ret, requestId);
}
-boost::shared_ptr<RequestManager::RequestMap> RequestManager::_getUnusedRequestId(Connection *connection, boost::uint16_t *requestId) {
- std::map<Connection*, boost::shared_ptr<RequestMap> >::iterator it = requestMaps.find(connection);
+// XXX Error handling!
+bool RequestManager::sendRequest(Connection *connection, boost::shared_ptr<Request> request) {
+ boost::unique_lock<boost::shared_mutex> lock(mutex);
- if(it == requestMaps.end()) {
+ if(!requestMap.isConnectionRegistered(connection)) {
Logger::log(Logger::CRITICAL, "Trying to send a request over an unregistered connecion.");
- return boost::shared_ptr<RequestMap>();
+ return false;
}
- boost::shared_ptr<RequestMap> requestMap = it->second;
+ uint16_t requestId = _getUnusedRequestId(connection);
+ requestMap.addRequest(connection, requestId, request);
+ request->connectSignalFinished(boost::bind(&RequestManager::handleRequestFinished, this, connection, requestId));
+ lock.unlock();
+
+ Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request));
- do {
- *requestId = _getRequestId();
- } while(requestMap->findRequest(*requestId));
+ return true;
+}
- return requestMap;
+boost::uint16_t RequestManager::_getUnusedRequestId(Connection *connection) {
+ while(true) {
+ boost::uint16_t requestId = _getRequestId();
+ if(!requestMap.findRequest(connection, requestId))
+ return requestId;
+ }
}
void RequestManager::registerConnection(Connection *connection) {
boost::lock_guard<boost::shared_mutex> lock(mutex);
- requestMaps.insert(std::make_pair(connection, new RequestMap()));
-
+ requestMap.registerConnection(connection);
connection->connectSignalReceive(boost::bind(&RequestManager::receiveHandler, this, connection, _1, _2));
}
diff --git a/src/Common/RequestManager.h b/src/Common/RequestManager.h
index bd1c12d..07a7c05 100644
--- a/src/Common/RequestManager.h
+++ b/src/Common/RequestManager.h
@@ -21,7 +21,6 @@
#define MAD_COMMON_REQUESTMANAGER_H_
#include "Request.h"
-#include <Net/ThreadManager.h>
#include <map>
#include <memory>
@@ -40,29 +39,49 @@ namespace Common {
class RequestManager : boost::noncopyable {
private:
- class RequestMap : private std::map<boost::uint16_t, boost::shared_ptr<RequestHandler> >, boost::noncopyable {
- public:
- bool addRequest(boost::uint16_t id, boost::shared_ptr<RequestHandler> info);
- boost::shared_ptr<RequestHandler> findRequest(boost::uint16_t id);
- void deleteRequest(boost::uint16_t id);
+ friend class RequestHandler;
+ class RequestMap : private boost::noncopyable {
private:
- void doDeleteRequest(boost::uint16_t id);
+ typedef std::map<boost::uint16_t, boost::shared_ptr<RequestHandler> > IdMap;
+ typedef std::map<const RequestHandler*, std::pair<Connection*, boost::uint16_t> > HandlerMap;
+
+ std::map<Connection*, IdMap> connectionMap;
+ HandlerMap handlerMap;
+
+ public:
+ void registerConnection(Connection *connection) {
+ connectionMap.insert(std::make_pair(connection, IdMap()));
+ }
+
+ void unregisterConnection(Connection *connection);
+
+ bool isConnectionRegistered(Connection *connection) const {
+ return connectionMap.count(connection);
+ }
+
+ bool addRequest(Connection *con, boost::uint16_t id, boost::shared_ptr<RequestHandler> info);
+ boost::shared_ptr<RequestHandler> findRequest(Connection *con, boost::uint16_t id);
+ void deleteRequest(Connection *con, boost::uint16_t id);
+
+ std::pair<Connection*, boost::uint16_t> getRequestInfo(const RequestHandler *requestHandler);
};
+
+
class RequestHandlerFactory {
protected:
RequestHandlerFactory() {}
public:
- virtual boost::shared_ptr<RequestHandler> createRequestHandler(Connection *connection, boost::uint16_t requestId) = 0;
+ virtual boost::shared_ptr<RequestHandler> createRequestHandler() = 0;
virtual ~RequestHandlerFactory() {}
};
template<class T> class SpecificRequestHandlerFactory : public RequestHandlerFactory {
public:
- virtual boost::shared_ptr<RequestHandler> createRequestHandler(Connection *connection, boost::uint16_t requestId) {
- return boost::shared_ptr<RequestHandler>(new T(connection, requestId));
+ virtual boost::shared_ptr<RequestHandler> createRequestHandler() {
+ return boost::shared_ptr<RequestHandler>(new T());
}
};
@@ -70,7 +89,8 @@ class RequestManager : boost::noncopyable {
boost::shared_mutex mutex;
- std::map<Connection*, boost::shared_ptr<RequestMap> > requestMaps;
+ RequestMap requestMap;
+
bool server;
boost::uint16_t lastRequestId;
@@ -80,9 +100,14 @@ class RequestManager : boost::noncopyable {
return lastRequestId+=2;
}
- void receiveHandler(Connection *connection, const XmlPacket &packet, boost::uint16_t requestId);
+ void receiveHandler(Connection *connection, boost::shared_ptr<const XmlPacket> packet, boost::uint16_t requestId);
+
+ void handleRequestFinished(Connection *con, boost::uint16_t requestId) {
+ boost::lock_guard<boost::shared_mutex> lock(mutex);
+ requestMap.deleteRequest(con, requestId);
+ }
- boost::shared_ptr<RequestMap> _getUnusedRequestId(Connection *connection, boost::uint16_t *requestId);
+ boost::uint16_t _getUnusedRequestId(Connection *connection);
bool send(Request *request);
@@ -113,7 +138,7 @@ class RequestManager : boost::noncopyable {
void unregisterConnection(Connection *connection) {
boost::lock_guard<boost::shared_mutex> lock(mutex);
- requestMaps.erase(connection);
+ requestMap.unregisterConnection(connection);
}
template <class T> void registerPacketType(const std::string &type) {
@@ -126,110 +151,7 @@ class RequestManager : boost::noncopyable {
requestHandlerFactories.erase(type);
}
- template <class T>
- boost::shared_ptr<Request> sendRequest0(Connection *connection, Request::slot_type slot = Request::empty_slot) {
- boost::unique_lock<boost::shared_mutex> lock(mutex);
-
- boost::shared_ptr<RequestMap> requestMap;
- boost::uint16_t requestId;
-
- requestMap = _getUnusedRequestId(connection, &requestId);
-
- if(!requestMap)
- return boost::shared_ptr<Request>();
-
- boost::shared_ptr<Request> request(new T(connection, requestId, slot));
- requestMap->addRequest(requestId, request);
- lock.unlock();
-
- Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request));
-
- return request;
- }
-
- template <class T, typename T1>
- boost::shared_ptr<Request> sendRequest1(Connection *connection, T1 t1, Request::slot_type slot = Request::empty_slot) {
- boost::unique_lock<boost::shared_mutex> lock(mutex);
-
- boost::shared_ptr<RequestMap> requestMap;
- boost::uint16_t requestId;
-
- requestMap = _getUnusedRequestId(connection, &requestId);
-
- if(!requestMap)
- return boost::shared_ptr<Request>();
-
- boost::shared_ptr<Request> request(new T(connection, requestId, slot, t1));
- requestMap->addRequest(requestId, request);
- lock.unlock();
-
- Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request));
-
- return request;
- }
-
- template <class T, typename T1, typename T2>
- boost::shared_ptr<Request> sendRequest2(Connection *connection, T1 t1, T2 t2, Request::slot_type slot = Request::empty_slot) {
- boost::unique_lock<boost::shared_mutex> lock(mutex);
-
- boost::shared_ptr<RequestMap> requestMap;
- boost::uint16_t requestId;
-
- requestMap = _getUnusedRequestId(connection, &requestId);
-
- if(!requestMap)
- return boost::shared_ptr<Request>();
-
- boost::shared_ptr<Request> request(new T(connection, requestId, slot, t1, t2));
- requestMap->addRequest(requestId, request);
- lock.unlock();
-
- Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request));
-
- return request;
- }
-
- template <class T, typename T1, typename T2, typename T3>
- boost::shared_ptr<Request> sendRequest3(Connection *connection, T1 t1, T2 t2, T3 t3, Request::slot_type slot = Request::empty_slot) {
- boost::unique_lock<boost::shared_mutex> lock(mutex);
-
- boost::shared_ptr<RequestMap> requestMap;
- boost::uint16_t requestId;
-
- requestMap = _getUnusedRequestId(connection, &requestId);
-
- if(!requestMap)
- return boost::shared_ptr<Request>();
-
- boost::shared_ptr<T> request(new T(connection, requestId, slot, t1, t2, t3));
- requestMap->addRequest(requestId, request);
- lock.unlock();
-
- Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request));
-
- return request;
- }
-
- template <class T, typename T1, typename T2, typename T3, typename T4>
- boost::shared_ptr<Request> sendRequest4(Connection *connection, T1 t1, T2 t2, T3 t3, T4 t4, Request::slot_type slot = Request::empty_slot) {
- boost::unique_lock<boost::shared_mutex> lock(mutex);
-
- boost::shared_ptr<RequestMap> requestMap;
- boost::uint16_t requestId;
-
- requestMap = _getUnusedRequestId(connection, &requestId);
-
- if(!requestMap)
- return boost::shared_ptr<Request>();
-
- boost::shared_ptr<Request> request(new T(connection, requestId, slot, t1, t2, t3, t4));
- requestMap->addRequest(requestId, request);
- lock.unlock();
-
- Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request));
-
- return request;
- }
+ bool sendRequest(Connection *connection, boost::shared_ptr<Request> request);
};
}
diff --git a/src/Common/Requests/DisconnectRequest.cpp b/src/Common/Requests/DisconnectRequest.cpp
index 3fac25b..249bbc1 100644
--- a/src/Common/Requests/DisconnectRequest.cpp
+++ b/src/Common/Requests/DisconnectRequest.cpp
@@ -30,19 +30,19 @@ void DisconnectRequest::sendRequest() {
sendPacket(packet);
}
-void DisconnectRequest::handlePacket(const XmlPacket &packet) {
- if(packet.getType() == "Error") {
- finishWithError(Net::Exception(packet["Where"], packet["ErrorCode"], packet["SubCode"], packet["SubSubCode"]));
+void DisconnectRequest::handlePacket(boost::shared_ptr<const XmlPacket> packet) {
+ if(packet->getType() == "Error") {
+ signalFinished(Net::Exception((*packet)["Where"], (*packet)["ErrorCode"], (*packet)["SubCode"], (*packet)["SubSubCode"]));
return;
}
- else if(packet.getType() != "OK") {
- finishWithError(Net::Exception(Net::Exception::UNEXPECTED_PACKET));
+ else if(packet->getType() != "OK") {
+ signalFinished(Net::Exception(Net::Exception::UNEXPECTED_PACKET));
return; // TODO Logging
}
getConnection()->disconnect();
- finish(packet);
+ signalFinished(packet);
}
}
diff --git a/src/Common/Requests/DisconnectRequest.h b/src/Common/Requests/DisconnectRequest.h
index b4fd4db..6da0ac9 100644
--- a/src/Common/Requests/DisconnectRequest.h
+++ b/src/Common/Requests/DisconnectRequest.h
@@ -29,11 +29,7 @@ namespace Requests {
class DisconnectRequest : public Request {
protected:
virtual void sendRequest();
- virtual void handlePacket(const XmlPacket &packet);
-
- public:
- DisconnectRequest(Connection *connection, uint16_t requestId, slot_type slot)
- : Request(connection, requestId, slot) {}
+ virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet);
};
}
diff --git a/src/Common/Requests/FSInfoRequest.h b/src/Common/Requests/FSInfoRequest.h
index 1db7753..250889a 100644
--- a/src/Common/Requests/FSInfoRequest.h
+++ b/src/Common/Requests/FSInfoRequest.h
@@ -28,8 +28,7 @@ namespace Requests {
class FSInfoRequest : public SimpleRequest {
public:
- FSInfoRequest(Connection *connection, uint16_t requestId, slot_type slot)
- : SimpleRequest(connection, requestId, slot, "FSInfo") {}
+ FSInfoRequest() : SimpleRequest("FSInfo") {}
};
}
diff --git a/src/Common/Requests/GroupListRequest.h b/src/Common/Requests/GroupListRequest.h
index 5aad003..b1e4115 100644
--- a/src/Common/Requests/GroupListRequest.h
+++ b/src/Common/Requests/GroupListRequest.h
@@ -28,8 +28,7 @@ namespace Requests {
class GroupListRequest : public SimpleRequest {
public:
- GroupListRequest(Connection *connection, uint16_t requestId, slot_type slot)
- : SimpleRequest(connection, requestId, slot, "ListGroups") {}
+ GroupListRequest() : SimpleRequest("ListGroups") {}
};
}
diff --git a/src/Common/Requests/GroupUserListRequest.h b/src/Common/Requests/GroupUserListRequest.h
index fd56a2f..bb735f1 100644
--- a/src/Common/Requests/GroupUserListRequest.h
+++ b/src/Common/Requests/GroupUserListRequest.h
@@ -34,8 +34,7 @@ class GroupUserListRequest : public Request {
virtual void sendRequest();
public:
- GroupUserListRequest(Connection *connection, uint16_t requestId, slot_type slot, unsigned long gid0)
- : Request(connection, requestId, slot), gid(gid0) {}
+ GroupUserListRequest(unsigned long gid0) : gid(gid0) {}
};
}
diff --git a/src/Common/Requests/IdentifyRequest.h b/src/Common/Requests/IdentifyRequest.h
index 3798909..3084ce6 100644
--- a/src/Common/Requests/IdentifyRequest.h
+++ b/src/Common/Requests/IdentifyRequest.h
@@ -36,8 +36,7 @@ class IdentifyRequest : public Common::Request {
virtual void sendRequest();
public:
- IdentifyRequest(Common::Connection *connection, uint16_t requestId, slot_type slot, const std::string &hostname0 = std::string())
- : Common::Request(connection, requestId, slot), hostname(hostname0) {}
+ IdentifyRequest(const std::string &hostname0 = std::string()) : hostname(hostname0) {}
};
}
diff --git a/src/Common/Requests/SimpleRequest.h b/src/Common/Requests/SimpleRequest.h
index 2c3070a..d381ecf 100644
--- a/src/Common/Requests/SimpleRequest.h
+++ b/src/Common/Requests/SimpleRequest.h
@@ -34,8 +34,7 @@ class SimpleRequest : public Request {
virtual void sendRequest();
- SimpleRequest(Connection *connection, uint16_t requestId, slot_type slot, const std::string &type0)
- : Request(connection, requestId, slot), type(type0) {}
+ SimpleRequest(const std::string &type0) : type(type0) {}
};
}
diff --git a/src/Common/Requests/StatusRequest.h b/src/Common/Requests/StatusRequest.h
index 0663fc4..b9b9f02 100644
--- a/src/Common/Requests/StatusRequest.h
+++ b/src/Common/Requests/StatusRequest.h
@@ -28,8 +28,7 @@ namespace Requests {
class StatusRequest : public SimpleRequest {
public:
- StatusRequest(Connection *connection, uint16_t requestId, slot_type slot)
- : SimpleRequest(connection, requestId, slot, "GetStatus") {}
+ StatusRequest() : SimpleRequest("GetStatus") {}
};
}
diff --git a/src/Common/Requests/UserGroupListRequest.h b/src/Common/Requests/UserGroupListRequest.h
index 2ee33d9..82db411 100644
--- a/src/Common/Requests/UserGroupListRequest.h
+++ b/src/Common/Requests/UserGroupListRequest.h
@@ -34,8 +34,7 @@ class UserGroupListRequest : public Request {
virtual void sendRequest();
public:
- UserGroupListRequest(Connection *connection, uint16_t requestId, slot_type slot, unsigned long uid0)
- : Request(connection, requestId, slot), uid(uid0) {}
+ UserGroupListRequest(unsigned long uid0) : uid(uid0) {}
};
}
diff --git a/src/Common/Requests/UserInfoRequest.h b/src/Common/Requests/UserInfoRequest.h
index 27cf1af..c9ac89b 100644
--- a/src/Common/Requests/UserInfoRequest.h
+++ b/src/Common/Requests/UserInfoRequest.h
@@ -34,8 +34,8 @@ class UserInfoRequest : public Request {
virtual void sendRequest();
public:
- UserInfoRequest(Connection *connection, uint16_t requestId, slot_type slot, unsigned long uid0)
- : Request(connection, requestId, slot), uid(uid0) {}
+ UserInfoRequest(unsigned long uid0)
+ : uid(uid0) {}
};
}
diff --git a/src/Common/Requests/UserListRequest.h b/src/Common/Requests/UserListRequest.h
index 7ab3ec7..9b69564 100644
--- a/src/Common/Requests/UserListRequest.h
+++ b/src/Common/Requests/UserListRequest.h
@@ -28,8 +28,7 @@ namespace Requests {
class UserListRequest : public SimpleRequest {
public:
- UserListRequest(Connection *connection, uint16_t requestId, slot_type slot)
- : SimpleRequest(connection, requestId, slot, "ListUsers") {}
+ UserListRequest() : SimpleRequest("ListUsers") {}
};
}