diff options
Diffstat (limited to 'backends/networking/curl')
-rw-r--r-- | backends/networking/curl/connectionmanager.cpp | 41 | ||||
-rw-r--r-- | backends/networking/curl/connectionmanager.h | 24 | ||||
-rw-r--r-- | backends/networking/curl/curljsonrequest.cpp | 2 | ||||
-rw-r--r-- | backends/networking/curl/curlrequest.cpp | 9 | ||||
-rw-r--r-- | backends/networking/curl/curlrequest.h | 2 | ||||
-rw-r--r-- | backends/networking/curl/request.h | 2 |
6 files changed, 67 insertions, 13 deletions
diff --git a/backends/networking/curl/connectionmanager.cpp b/backends/networking/curl/connectionmanager.cpp index 8428bd25f0..b448d8e514 100644 --- a/backends/networking/curl/connectionmanager.cpp +++ b/backends/networking/curl/connectionmanager.cpp @@ -50,12 +50,16 @@ void ConnectionManager::registerEasyHandle(CURL *easy) { int32 ConnectionManager::addRequest(Request *request) { int32 newId = _nextId++; - _requests[newId] = request; + _requests[newId] = RequestInfo(newId, request); request->setId(newId); if (!_timerStarted) startTimer(); return newId; } +RequestInfo &ConnectionManager::getRequestInfo(int32 id) { + return _requests[id]; +} + //private goes here: void connectionsThread(void *ignored) { @@ -87,15 +91,34 @@ void ConnectionManager::handle() { void ConnectionManager::interateRequests() { //call handle() of all running requests (so they can do their work) debug("handling %d request(s)", _requests.size()); - for (Common::HashMap<int32, Request *>::iterator i = _requests.begin(); i != _requests.end();) { - Request *request = i->_value; - if (request && request->handle()) { - delete request; - //_requests.erase(i); - _requests[i->_key] = 0; - ++i; //that's temporary - } else ++i; + Common::Array<int32> idsToRemove; + for (Common::HashMap<int32, RequestInfo>::iterator i = _requests.begin(); i != _requests.end(); ++i) { + RequestInfo &info = _requests[i->_key]; + + switch(info.state) { + case FINISHED: + delete info.request; + info.request = 0; + idsToRemove.push_back(info.id); + break; + + case PROCESSING: + info.request->handle(); + break; + + case RETRY: + if (info.retryInSeconds > 0) --info.retryInSeconds; + else { + info.state = PROCESSING; + info.request->restart(); + } + + default: + ; //nothing to do + } } + for (uint32 i = 0; i < idsToRemove.size(); ++i) + _requests.erase(idsToRemove[i]); if (_requests.empty()) stopTimer(); } diff --git a/backends/networking/curl/connectionmanager.h b/backends/networking/curl/connectionmanager.h index 9651a0166a..9ae52b3eeb 100644 --- a/backends/networking/curl/connectionmanager.h +++ b/backends/networking/curl/connectionmanager.h @@ -36,12 +36,30 @@ namespace Networking { class NetworkReadStream; +enum RequestState { + PROCESSING, + PAUSED, + RETRY, + FINISHED +}; + +struct RequestInfo { + int32 id; + Request *request; + RequestState state; + void *data; + uint32 retryInSeconds; + + RequestInfo() : id(-1), request(0), state(FINISHED), data(0), retryInSeconds(0) {} + RequestInfo(int32 rqId, Request *rq) : id(rqId), request(rq), state(PROCESSING), data(0), retryInSeconds(0) {} +}; + class ConnectionManager : public Common::Singleton<ConnectionManager> { friend void connectionsThread(void *); //calls handle() CURLM *_multi; bool _timerStarted; - Common::HashMap<int32, Request *> _requests; + Common::HashMap<int32, RequestInfo> _requests; int32 _nextId; void startTimer(int interval = 1000000); //1 second is the default interval @@ -70,7 +88,9 @@ public: * * @return generated Request's id, which might be used to get its status */ - int32 addRequest(Request *request); + int32 addRequest(Request *request); + + RequestInfo &getRequestInfo(int32 id); }; /** Shortcut for accessing the connection manager. */ diff --git a/backends/networking/curl/curljsonrequest.cpp b/backends/networking/curl/curljsonrequest.cpp index 0366e3b403..21c0a0f644 100644 --- a/backends/networking/curl/curljsonrequest.cpp +++ b/backends/networking/curl/curljsonrequest.cpp @@ -23,6 +23,7 @@ #define FORBIDDEN_SYMBOL_ALLOW_ALL #include "backends/networking/curl/curljsonrequest.h" +#include "backends/networking/curl/connectionmanager.h" #include "backends/networking/curl/networkreadstream.h" #include "common/debug.h" #include "common/json.h" @@ -68,6 +69,7 @@ bool CurlJsonRequest::handle() { if (_stream->httpResponseCode() != 200) warning("HTTP response code is not 200 OK (it's %ld)", _stream->httpResponseCode()); + ConnMan.getRequestInfo(_id).state = Networking::FINISHED; if (_callback) { char *contents = getPreparedContents(); if (_stream->httpResponseCode() != 200) diff --git a/backends/networking/curl/curlrequest.cpp b/backends/networking/curl/curlrequest.cpp index e13adaca59..e1c8f2b18c 100644 --- a/backends/networking/curl/curlrequest.cpp +++ b/backends/networking/curl/curlrequest.cpp @@ -42,13 +42,20 @@ bool CurlRequest::handle() { if (_stream && _stream->eos()) { if (_stream->httpResponseCode() != 200) - warning("HTTP response code is not 200 OK (it's %ld)", _stream->httpResponseCode()); + warning("HTTP response code is not 200 OK (it's %ld)", _stream->httpResponseCode()); + ConnMan.getRequestInfo(_id).state = Networking::FINISHED; return true; } return false; } +void CurlRequest::restart() { + if (_stream) delete _stream; + _stream = 0; + //with no stream available next handle() will create another one +} + void CurlRequest::addHeader(Common::String header) { _headersList = curl_slist_append(_headersList, header.c_str()); } diff --git a/backends/networking/curl/curlrequest.h b/backends/networking/curl/curlrequest.h index 22f50be418..ec1a9e33c6 100644 --- a/backends/networking/curl/curlrequest.h +++ b/backends/networking/curl/curlrequest.h @@ -44,9 +44,9 @@ public: virtual ~CurlRequest(); virtual bool handle(); + virtual void restart(); void addHeader(Common::String header); - void addPostField(Common::String header); /** Start this Request with ConnMan. Returns its ReadStream. */ diff --git a/backends/networking/curl/request.h b/backends/networking/curl/request.h index 0265d3e2f3..136f007920 100644 --- a/backends/networking/curl/request.h +++ b/backends/networking/curl/request.h @@ -51,6 +51,8 @@ public: virtual bool handle() = 0; + virtual void restart() = 0; + void setId(int32 id) { _id = id; } }; |