From 9ad913e5f181269050f0e10dac9589ac18733c31 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 20 May 2009 18:00:47 +0200 Subject: RequestManager ist jetzt Thread-sicher --- src/Common/RequestManager.cpp | 88 ++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 59 deletions(-) (limited to 'src/Common/RequestManager.cpp') diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp index c36bd76..8940339 100644 --- a/src/Common/RequestManager.cpp +++ b/src/Common/RequestManager.cpp @@ -29,12 +29,7 @@ namespace Common { RequestManager RequestManager::requestManager; -RequestManager::RequestMap::~RequestMap() { - for(iterator it = begin(); it != end(); ++it) - delete it->second; -} - -bool RequestManager::RequestMap::addRequest(uint16_t id, RequestHandler *info) { +bool RequestManager::RequestMap::addRequest(boost::uint16_t id, boost::shared_ptr info) { if(!insert(std::make_pair(id, info)).second) return false; @@ -43,28 +38,23 @@ bool RequestManager::RequestMap::addRequest(uint16_t id, RequestHandler *info) { return true; } -RequestHandler* RequestManager::RequestMap::findRequest(uint16_t id) { +boost::shared_ptr RequestManager::RequestMap::findRequest(boost::uint16_t id) { iterator it = find(id); if(it == end()) - return 0; + return boost::shared_ptr(); return it->second; } -bool RequestManager::RequestMap::deleteRequest(uint16_t id) { - iterator it = find(id); - if(it == end()) - return false; - - delete it->second; - - erase(it); - return true; +bool RequestManager::RequestMap::deleteRequest(boost::uint16_t id) { + return erase(id); } -void RequestManager::receiveHandler(Connection *connection, const XmlPacket &packet, uint16_t requestId) { - std::map::iterator it = requestMaps.find(connection); +void RequestManager::receiveHandler(Connection *connection, const XmlPacket &packet, boost::uint16_t requestId) { + boost::upgrade_lock lock(mutex); + + std::map >::iterator it = requestMaps.find(connection); if(it == requestMaps.end()) { // TODO: Error Logger::log(Logger::ERROR, "Received a packet from an unregistered connection."); @@ -72,25 +62,33 @@ void RequestManager::receiveHandler(Connection *connection, const XmlPacket &pac return; } - RequestMap *requestMap = it->second; - RequestHandler *request = requestMap->findRequest(requestId); + boost::shared_ptr requestMap = it->second; + boost::shared_ptr request = requestMap->findRequest(requestId); if(request) { + lock.unlock(); request->handlePacket(packet); return; } - std::map::iterator factoryIt = requestHandlerFactories.find(packet.getType()); + std::map >::iterator factoryIt = requestHandlerFactories.find(packet.getType()); if(factoryIt != requestHandlerFactories.end()) { - request = factoryIt->second->createRequestHandler(connection, requestId); + { + boost::upgrade_to_unique_lock upgradeLock(lock); + + request = factoryIt->second->createRequestHandler(connection, requestId); + requestMap->addRequest(requestId, request); + } - requestMap->addRequest(requestId, request); + lock.unlock(); request->handlePacket(packet); return; } + lock.unlock(); + Logger::logf(Logger::ERROR, "Received an unexpected packet with type '%s'.", packet.getType().c_str()); XmlPacket ret; @@ -100,62 +98,34 @@ void RequestManager::receiveHandler(Connection *connection, const XmlPacket &pac connection->sendPacket(ret, requestId); } -RequestManager::RequestMap* RequestManager::getUnusedRequestId(Connection *connection, uint16_t *requestId) { - std::map::iterator it = requestMaps.find(connection); +boost::shared_ptr RequestManager::_getUnusedRequestId(Connection *connection, boost::uint16_t *requestId) { + std::map >::iterator it = requestMaps.find(connection); if(it == requestMaps.end()) { Logger::log(Logger::CRITICAL, "Trying to send a request over an unregistered connecion."); - return 0; + return boost::shared_ptr(); } - RequestMap *requestMap = it->second; + boost::shared_ptr requestMap = it->second; do { - *requestId = getRequestId(); + *requestId = _getRequestId(); } while(requestMap->findRequest(*requestId)); return requestMap; } void RequestManager::registerConnection(Connection *connection) { + boost::lock_guard lock(mutex); + requestMaps.insert(std::make_pair(connection, new RequestMap())); connection->signalReceive().connect(boost::bind(&RequestManager::receiveHandler, this, connection, _1, _2)); } -void RequestManager::unregisterConnection(Connection *connection) { - std::map::iterator it = requestMaps.find(connection); - - if(it != requestMaps.end()) { - delete it->second; - requestMaps.erase(it); - } -} - -void RequestManager::unregisterPacketType(const std::string &type) { - std::map::iterator it = requestHandlerFactories.find(type); - - if(it == requestHandlerFactories.end()) - return; - - delete it->second; - - requestHandlerFactories.erase(it); -} - RequestManager::RequestManager() : server(false), lastRequestId(-1) { registerPacketType("Disconnect"); } -RequestManager::~RequestManager() { - unregisterPacketType("Disconnect"); - - for(std::map::iterator it = requestMaps.begin(); it != requestMaps.end(); ++it) - delete it->second; - - for(std::map::iterator it = requestHandlerFactories.begin(); it != requestHandlerFactories.end(); ++it) - delete it->second; -} - } } -- cgit v1.2.3