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.h | 139 ++++++++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 58 deletions(-) (limited to 'src/Common/RequestManager.h') diff --git a/src/Common/RequestManager.h b/src/Common/RequestManager.h index e9ce189..d9e7fbb 100644 --- a/src/Common/RequestManager.h +++ b/src/Common/RequestManager.h @@ -26,7 +26,8 @@ #include #include -#include +#include +#include namespace Mad { @@ -36,21 +37,13 @@ class Packet; namespace Common { -class RequestManager { +class RequestManager : boost::noncopyable { private: - class RequestMap : private std::map { - private: - // Prevent shallow copy - RequestMap(const RequestMap &o); - RequestMap& operator=(const RequestMap &o); - + class RequestMap : private std::map >, boost::noncopyable { public: - RequestMap() {} - ~RequestMap(); - - bool addRequest(uint16_t id, RequestHandler *info); - RequestHandler* findRequest(uint16_t id); - bool deleteRequest(uint16_t id); + bool addRequest(boost::uint16_t id, boost::shared_ptr info); + boost::shared_ptr findRequest(boost::uint16_t id); + bool deleteRequest(boost::uint16_t id); }; class RequestHandlerFactory { @@ -58,36 +51,34 @@ class RequestManager { RequestHandlerFactory() {} public: - virtual RequestHandler* createRequestHandler(Connection *connection, uint16_t requestId) = 0; + virtual boost::shared_ptr createRequestHandler(Connection *connection, boost::uint16_t requestId) = 0; virtual ~RequestHandlerFactory() {} }; template class SpecificRequestHandlerFactory : public RequestHandlerFactory { public: - virtual RequestHandler* createRequestHandler(Connection *connection, uint16_t requestId) { - return new T(connection, requestId); + virtual boost::shared_ptr createRequestHandler(Connection *connection, boost::uint16_t requestId) { + return boost::shared_ptr(new T(connection, requestId)); } }; static RequestManager requestManager; - std::map requestMaps; + boost::shared_mutex mutex; + + std::map > requestMaps; bool server; - uint16_t lastRequestId; + boost::uint16_t lastRequestId; - std::map requestHandlerFactories; + std::map > requestHandlerFactories; - uint16_t getRequestId() { + boost::uint16_t _getRequestId() { return lastRequestId+=2; } - // Prevent shallow copy - RequestManager(const RequestManager &o); - RequestManager& operator=(const RequestManager &o); - - void receiveHandler(Connection *connection, const XmlPacket &packet, uint16_t requestId); + void receiveHandler(Connection *connection, const XmlPacket &packet, boost::uint16_t requestId); - RequestMap* getUnusedRequestId(Connection *connection, uint16_t *requestId); + boost::shared_ptr _getUnusedRequestId(Connection *connection, boost::uint16_t *requestId); bool send(Request *request); @@ -98,8 +89,14 @@ class RequestManager { return &requestManager; } - bool isServer() const {return server;} + bool isServer() { + boost::shared_lock lock(mutex); + return server; + } + void setServer(bool newServer) { + boost::lock_guard lock(mutex); + server = newServer; if(server) @@ -109,100 +106,126 @@ class RequestManager { } void registerConnection(Connection *connection); - void unregisterConnection(Connection *connection); + + void unregisterConnection(Connection *connection) { + boost::lock_guard lock(mutex); + requestMaps.erase(connection); + } template void registerPacketType(const std::string &type) { - requestHandlerFactories.insert(std::make_pair(type, new SpecificRequestHandlerFactory())); + boost::lock_guard lock(mutex); + requestHandlerFactories.insert(std::make_pair(type, boost::shared_ptr >(new SpecificRequestHandlerFactory()))); } - void unregisterPacketType(const std::string &type); + void unregisterPacketType(const std::string &type) { + boost::lock_guard lock(mutex); + requestHandlerFactories.erase(type); + } template bool sendRequest(Connection *connection, Request::slot_type slot) { - RequestMap *requestMap; - uint16_t requestId; + boost::unique_lock lock(mutex); - requestMap = getUnusedRequestId(connection, &requestId); + boost::shared_ptr requestMap; + boost::uint16_t requestId; + + requestMap = _getUnusedRequestId(connection, &requestId); if(!requestMap) return false; - Request *request = new T(connection, requestId, slot); - request->sendRequest(); + boost::shared_ptr request(new T(connection, requestId, slot)); requestMap->addRequest(requestId, request); + lock.unlock(); + + request->sendRequest(); return true; } template bool sendRequest(Connection *connection, Request::slot_type slot, T1 t1) { - RequestMap *requestMap; - uint16_t requestId; + boost::unique_lock lock(mutex); - requestMap = getUnusedRequestId(connection, &requestId); + boost::shared_ptr requestMap; + boost::uint16_t requestId; + + requestMap = _getUnusedRequestId(connection, &requestId); if(!requestMap) return false; - Request *request = new T(connection, requestId, slot, t1); - request->sendRequest(); + boost::shared_ptr request(new T(connection, requestId, slot, t1)); requestMap->addRequest(requestId, request); + lock.unlock(); + + request->sendRequest(); return true; } template bool sendRequest(Connection *connection, Request::slot_type slot, T1 t1, T2 t2) { - RequestMap *requestMap; - uint16_t requestId; + boost::unique_lock lock(mutex); - requestMap = getUnusedRequestId(connection, &requestId); + boost::shared_ptr requestMap; + boost::uint16_t requestId; + + requestMap = _getUnusedRequestId(connection, &requestId); if(!requestMap) return false; - Request *request = new T(connection, requestId, slot, t1, t2); - request->sendRequest(); + boost::shared_ptr request(new T(connection, requestId, slot, t1, t2)); requestMap->addRequest(requestId, request); + lock.unlock(); + + request->sendRequest(); return true; } template bool sendRequest(Connection *connection, Request::slot_type slot, T1 t1, T2 t2, T3 t3) { - RequestMap *requestMap; - uint16_t requestId; + boost::unique_lock lock(mutex); - requestMap = getUnusedRequestId(connection, &requestId); + boost::shared_ptr requestMap; + boost::uint16_t requestId; + + requestMap = _getUnusedRequestId(connection, &requestId); if(!requestMap) return false; - Request *request = new T(connection, requestId, slot, t1, t2, t3); - request->sendRequest(); + boost::shared_ptr request(new T(connection, requestId, slot, t1, t2, t3)); requestMap->addRequest(requestId, request); + lock.unlock(); + + request->sendRequest(); return true; } template bool sendRequest(Connection *connection, Request::slot_type slot, T1 t1, T2 t2, T3 t3, T4 t4) { - RequestMap *requestMap; - uint16_t requestId; + boost::unique_lock lock(mutex); - requestMap = getUnusedRequestId(connection, &requestId); + boost::shared_ptr requestMap; + boost::uint16_t requestId; + + requestMap = _getUnusedRequestId(connection, &requestId); if(!requestMap) return false; - Request *request = new T(connection, requestId, slot, t1, t2, t3, t4); - request->sendRequest(); + boost::shared_ptr request(new T(connection, requestId, slot, t1, t2, t3, t4)); requestMap->addRequest(requestId, request); + lock.unlock(); + + request->sendRequest(); return true; } - - virtual ~RequestManager(); }; } -- cgit v1.2.3