From 1508969d508e41de824d1d1227be708136760cfa Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 8 Jul 2008 22:31:29 +0200 Subject: Request-Verarbeitung ?berarbeitet --- aclocal.m4 | 2 +- src/Common/Makefile.am | 2 +- src/Common/Makefile.in | 2 +- src/Common/Request/DisconnectRequest.h | 44 ++++++++++++++++++++++-- src/Common/Request/Makefile.am | 2 +- src/Common/Request/Makefile.in | 2 +- src/Common/Request/PingRequest.h | 47 ++++++++++++++++++++++++-- src/Common/Request/Request.h | 57 +++++++++++++++++++++++++++++++ src/Common/RequestInfo.h | 45 ------------------------ src/Common/RequestManager.cpp | 62 +++++++++++----------------------- src/Common/RequestManager.h | 28 +++++++++++++-- src/Core/ConfigManager.cpp | 2 -- src/madc.cpp | 4 +-- 13 files changed, 193 insertions(+), 106 deletions(-) create mode 100644 src/Common/Request/Request.h delete mode 100644 src/Common/RequestInfo.h diff --git a/aclocal.m4 b/aclocal.m4 index b1826ac..cc442ca 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -21,7 +21,7 @@ To do so, use the procedure documented by the package, typically `autoreconf'.]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# serial 52 Debian 1.5.26-1ubuntu1 AC_PROG_LIBTOOL +# serial 52 Debian 1.5.26-4 AC_PROG_LIBTOOL # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) diff --git a/src/Common/Makefile.am b/src/Common/Makefile.am index 1e8a524..1958a1c 100644 --- a/src/Common/Makefile.am +++ b/src/Common/Makefile.am @@ -3,4 +3,4 @@ SUBDIRS = Request noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = ConfigManager.cpp RequestManager.cpp -noinst_HEADERS = ConfigManager.h RequestInfo.h RequestManager.h Util.h +noinst_HEADERS = ConfigManager.h RequestManager.h Util.h diff --git a/src/Common/Makefile.in b/src/Common/Makefile.in index f47fa8d..da63be0 100644 --- a/src/Common/Makefile.in +++ b/src/Common/Makefile.in @@ -192,7 +192,7 @@ top_srcdir = @top_srcdir@ SUBDIRS = Request noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = ConfigManager.cpp RequestManager.cpp -noinst_HEADERS = ConfigManager.h RequestInfo.h RequestManager.h Util.h +noinst_HEADERS = ConfigManager.h RequestManager.h Util.h all: all-recursive .SUFFIXES: diff --git a/src/Common/Request/DisconnectRequest.h b/src/Common/Request/DisconnectRequest.h index 309504d..9023c13 100644 --- a/src/Common/Request/DisconnectRequest.h +++ b/src/Common/Request/DisconnectRequest.h @@ -20,15 +20,53 @@ #ifndef DISCONNECTREQUEST_H_ #define DISCONNECTREQUEST_H_ -#include "../RequestInfo.h" +#include "Request.h" +#include "../RequestManager.h" +#include +#include namespace Mad { namespace Common { namespace Request { -class DisconnectRequest: public RequestInfo { +class DisconnectRequest: public Request { + private: + DisconnectRequest() {} + public: - DisconnectRequest() : RequestInfo(TYPE_DISCONNECT) {} + static bool send(Net::Connection *connection, RequestManager &requestManager) { + Request *request = new DisconnectRequest(); + + if(requestManager.sendRequest(connection, request)) + return true; + + delete request; + return false; + } + + virtual bool sendRequest(Net::Connection *connection, unsigned short requestId) { + if(isSent()) + return false; + + if(!connection->send(Net::Packet(Net::Packet::TYPE_DISCONNECT_REQ, requestId))) + return false; + + setSent(); + return true; + } + + virtual bool handlePacket(Net::Connection *connection, const Net::Packet &packet) { + if(isFinished()) + return false; + + if(packet.getType() != Net::Packet::TYPE_DISCONNECT_REP) + return false; // TODO Logging + + connection->disconnect(); + + setFinished(); + return true; + } }; } diff --git a/src/Common/Request/Makefile.am b/src/Common/Request/Makefile.am index 35e432b..17e47fe 100644 --- a/src/Common/Request/Makefile.am +++ b/src/Common/Request/Makefile.am @@ -1 +1 @@ -noinst_HEADERS = DisconnectRequest.h PingRequest.h +noinst_HEADERS = DisconnectRequest.h PingRequest.h Request.h diff --git a/src/Common/Request/Makefile.in b/src/Common/Request/Makefile.in index 7d68911..d96c0a7 100644 --- a/src/Common/Request/Makefile.in +++ b/src/Common/Request/Makefile.in @@ -162,7 +162,7 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -noinst_HEADERS = DisconnectRequest.h PingRequest.h +noinst_HEADERS = DisconnectRequest.h PingRequest.h Request.h all: all-am .SUFFIXES: diff --git a/src/Common/Request/PingRequest.h b/src/Common/Request/PingRequest.h index 35a0171..92e3c1a 100644 --- a/src/Common/Request/PingRequest.h +++ b/src/Common/Request/PingRequest.h @@ -20,15 +20,56 @@ #ifndef MAD_COMMON_REQUEST_PINGREQUEST_H_ #define MAD_COMMON_REQUEST_PINGREQUEST_H_ -#include "../RequestInfo.h" +#include "Request.h" +#include "../RequestManager.h" +#include +#include + +#include namespace Mad { namespace Common { namespace Request { -class PingRequest : public RequestInfo { +class PingRequest : public Request { + private: + PingRequest() {} + public: - PingRequest() : RequestInfo(TYPE_PING) {} + static bool send(Net::Connection *connection, RequestManager &requestManager) { + Request *request = new PingRequest(); + + if(requestManager.sendRequest(connection, request)) + return true; + + delete request; + return false; + } + + virtual bool sendRequest(Net::Connection *connection, unsigned short requestId) { + if(isSent()) + return false; + + if(!connection->send(Net::Packet(Net::Packet::TYPE_PING, requestId))) + return false; + + setSent(); + return true; + } + + virtual bool handlePacket(Net::Connection*, const Net::Packet &packet) { + if(isFinished()) + return false; + + if(packet.getType() != Net::Packet::TYPE_PONG) + return false; // TODO Logging + + std::cout << "Received ping reply." << std::endl; + std::cout << " Request ID: " << packet.getRequestId() << std::endl; + + setFinished(); + return true; + } }; } diff --git a/src/Common/Request/Request.h b/src/Common/Request/Request.h new file mode 100644 index 0000000..211b2cd --- /dev/null +++ b/src/Common/Request/Request.h @@ -0,0 +1,57 @@ +/* + * Request.h + * + * Copyright (C) 2008 Matthias Schiffer + * + * 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 . + */ + +#ifndef MAD_COMMON_REQUEST_REQUEST_H_ +#define MAD_COMMON_REQUEST_REQUEST_H_ + +namespace Mad { + +namespace Net { +class Connection; +class Packet; +} + +namespace Common { +namespace Request { + +class Request { + private: + bool sent, finished; + + protected: + Request() : sent(false), finished(false) {} + + void setSent() {sent = true;} + void setFinished() {finished = true;} + + public: + virtual ~Request() {} + + bool isSent() const {return sent;} + bool isFinished() const {return finished;} + + virtual bool sendRequest(Net::Connection *connection, unsigned short requestId) = 0; + virtual bool handlePacket(Net::Connection *connection, const Net::Packet &packet) = 0; +}; + +} +} +} + +#endif /* MAD_COMMON_REQUEST_REQUEST_H_ */ diff --git a/src/Common/RequestInfo.h b/src/Common/RequestInfo.h deleted file mode 100644 index 943cf31..0000000 --- a/src/Common/RequestInfo.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * RequestInfo.h - * - * Copyright (C) 2008 Matthias Schiffer - * - * 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 . - */ - -#ifndef MAD_COMMON_REQUESTINFO_H_ -#define MAD_COMMON_REQUESTINFO_H_ - -namespace Mad { -namespace Common { - -class RequestInfo { - public: - enum Type { - TYPE_PING, TYPE_DISCONNECT - }; - - private: - Type type; - - protected: - RequestInfo(Type type0) : type(type0) {} - - public: - Type getType() const {return type;} -}; - -} -} - -#endif /* MAD_COMMON_REQUESTINFO_H_ */ diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp index 34a9141..2d79b25 100644 --- a/src/Common/RequestManager.cpp +++ b/src/Common/RequestManager.cpp @@ -35,7 +35,16 @@ void RequestManager::receiveHandler(Net::Connection *connection, const Net::Pack } RequestMap &requestInfo = it->second; - RequestMap::iterator it2; + Request::Request *request = requestInfo.findRequest(packet.getRequestId()); + + if(request) { + request->handlePacket(connection, packet); + + if(request->isFinished()) + requestInfo.deleteRequest(packet.getRequestId()); + + return; + } switch(packet.getType()) { case Net::Packet::TYPE_PING: @@ -44,40 +53,16 @@ void RequestManager::receiveHandler(Net::Connection *connection, const Net::Pack connection->send(Net::Packet(Net::Packet::TYPE_PONG, packet.getRequestId(), packet.getData(), packet.getLength())); break; - case Net::Packet::TYPE_PONG: - it2 = requestInfo.find(packet.getRequestId()); - if(it2 == requestInfo.end() || it2->second.getType() != RequestInfo::TYPE_PING) { - // TODO: Error - std::cerr << "Received an unexpected ping reply." << std::endl; - - return; - } - - requestInfo.erase(it2); - - std::cout << "Received ping reply." << std::endl; - std::cout << " Request ID: " << packet.getRequestId() << std::endl; - break; case Net::Packet::TYPE_DISCONNECT_REQ: connection->send(Net::Packet(Net::Packet::TYPE_DISCONNECT_REP, packet.getRequestId())); connection->disconnect(); break; - case Net::Packet::TYPE_DISCONNECT_REP: - it2 = requestInfo.find(packet.getRequestId()); - if(it2 == requestInfo.end() || it2->second.getType() != RequestInfo::TYPE_DISCONNECT) { - // TODO: Error - std::cerr << "Received an unexpected disconnect reply." << std::endl; - - return; - } - - requestInfo.erase(it2); - - connection->disconnect(); + default: + std::cerr << "Received an unexpected packet." << std::endl; } } -bool RequestManager::sendRequest(Net::Connection *connection, RequestInfo requestData) { +bool RequestManager::sendRequest(Net::Connection *connection, Request::Request *request) { std::map::iterator it = requestMap.find(connection); if(it == requestMap.end()) @@ -85,24 +70,15 @@ bool RequestManager::sendRequest(Net::Connection *connection, RequestInfo reques RequestMap &requestInfo = it->second; - unsigned short request; + unsigned short id; do { - request = getRequestId(); - } while(requestInfo.find(request) != requestInfo.end()); + id = getRequestId(); + } while(requestInfo.findRequest(id)); - switch(requestData.getType()) { - case RequestInfo::TYPE_PING: - if(!connection->send(Net::Packet(Net::Packet::TYPE_PING, request))) - return false; - - requestInfo.insert(std::make_pair(request, requestData)); - break; - case RequestInfo::TYPE_DISCONNECT: - if(!connection->send(Net::Packet(Net::Packet::TYPE_DISCONNECT_REQ, request))) - return false; + if(!request->sendRequest(connection, id)) + return false; - requestInfo.insert(std::make_pair(request, requestData)); - } + requestInfo.addRequest(id, request); return true; } diff --git a/src/Common/RequestManager.h b/src/Common/RequestManager.h index a5861dd..fde8f3e 100644 --- a/src/Common/RequestManager.h +++ b/src/Common/RequestManager.h @@ -20,7 +20,7 @@ #ifndef MAD_COMMON_REQUESTMANAGER_H_ #define MAD_COMMON_REQUESTMANAGER_H_ -#include "RequestInfo.h" +#include "Request/Request.h" #include #include @@ -29,7 +29,29 @@ namespace Common { class RequestManager { private: - typedef std::map RequestMap; + class RequestMap : private std::map { + public: + ~RequestMap() { + for(iterator it = begin(); it != end(); ++it) + delete it->second; + } + + bool addRequest(unsigned short id, Request::Request *info) { + return insert(std::make_pair(id, info)).second; + } + + Request::Request* findRequest(unsigned short id) { + iterator it = find(id); + if(it == end()) + return 0; + + return it->second; + } + + bool deleteRequest(unsigned short id) { + return erase(id); + } + }; std::map requestMap; unsigned short requestId; @@ -51,7 +73,7 @@ class RequestManager { requestMap.erase(connection); } - bool sendRequest(Net::Connection *connection, RequestInfo requestData); + bool sendRequest(Net::Connection *connection, Request::Request *request); RequestManager() : requestId(0) {} diff --git a/src/Core/ConfigManager.cpp b/src/Core/ConfigManager.cpp index e1e5021..b4c81bc 100644 --- a/src/Core/ConfigManager.cpp +++ b/src/Core/ConfigManager.cpp @@ -20,8 +20,6 @@ #include "ConfigManager.h" #include -#include - namespace Mad { namespace Core { diff --git a/src/madc.cpp b/src/madc.cpp index 3f5d5bc..d6a06e3 100644 --- a/src/madc.cpp +++ b/src/madc.cpp @@ -43,8 +43,8 @@ int main() { requestManager.registerConnection(connection); - requestManager.sendRequest(connection, Mad::Common::Request::PingRequest()); - requestManager.sendRequest(connection, Mad::Common::Request::DisconnectRequest()); + Mad::Common::Request::PingRequest::send(connection, requestManager); + Mad::Common::Request::DisconnectRequest::send(connection, requestManager); while(connection->isConnected()) { struct pollfd fd = connection->getPollfd(); -- cgit v1.2.3