summaryrefslogtreecommitdiffstats
path: root/src/Common/RequestManager.cpp
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/RequestManager.cpp
parent50d92f64547c5c06851976ceab5ed631ec93f647 (diff)
downloadmad-0b27c37fe95c6aced613d51a3624f8930a96ad3f.tar
mad-0b27c37fe95c6aced613d51a3624f8930a96ad3f.zip
RequestHandler-Interface ?berarbeitet
Diffstat (limited to 'src/Common/RequestManager.cpp')
-rw-r--r--src/Common/RequestManager.cpp117
1 files changed, 80 insertions, 37 deletions
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));
}