1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef BACKENDS_NETWORKING_CURL_CONNECTIONMANAGER_H 24 #define BACKENDS_NETWORKING_CURL_CONNECTIONMANAGER_H 25 26 #include "backends/networking/curl/request.h" 27 #include "common/str.h" 28 #include "common/singleton.h" 29 #include "common/hashmap.h" 30 #include "common/mutex.h" 31 32 typedef void CURL; 33 typedef void CURLM; 34 struct curl_slist; 35 36 namespace Networking { 37 38 class NetworkReadStream; 39 40 class ConnectionManager : public Common::Singleton<ConnectionManager> { 41 static const uint32 FRAMES_PER_SECOND = 20; 42 static const uint32 TIMER_INTERVAL = 1000000 / FRAMES_PER_SECOND; 43 static const uint32 CLOUD_PERIOD = 20; //every 20th frame 44 static const uint32 CURL_PERIOD = 1; //every frame 45 46 friend void connectionsThread(void *); //calls handle() 47 48 typedef Common::BaseCallback<Request *> *RequestCallback; 49 50 /** 51 * RequestWithCallback is used by ConnectionManager to 52 * storage the Request and a callback which should be 53 * called on Request delete. 54 * 55 * Usually one won't need to pass such callback, but 56 * in some cases you'd like to know whether Request is 57 * still running. 58 * 59 * For example, Cloud::Storage is keeping track of how 60 * many Requests are running, and thus it needs to know 61 * that Request was destroyed to decrease its counter. 62 * 63 * onDeleteCallback is called with *invalid* pointer. 64 * ConnectionManager deletes Request first and then passes 65 * the pointer to the callback. One may use the address 66 * to find it in own HashMap or Array and remove it. 67 * So, again, this pointer is for information only. One 68 * cannot use it. 69 */ 70 struct RequestWithCallback { 71 Request *request; 72 RequestCallback onDeleteCallback; 73 requestRequestWithCallback74 RequestWithCallback(Request *rq = nullptr, RequestCallback cb = nullptr): request(rq), onDeleteCallback(cb) {} 75 }; 76 77 CURLM *_multi; 78 bool _timerStarted; 79 Common::Array<RequestWithCallback> _requests, _addedRequests; 80 Common::Mutex _handleMutex, _addedRequestsMutex; 81 uint32 _frame; 82 83 void startTimer(int interval = TIMER_INTERVAL); 84 void stopTimer(); 85 void handle(); 86 void interateRequests(); 87 void processTransfers(); 88 bool hasAddedRequests(); 89 90 public: 91 ConnectionManager(); 92 virtual ~ConnectionManager(); 93 94 /** 95 * All libcurl transfers are going through this ConnectionManager. 96 * So, if you want to start any libcurl transfer, you must create 97 * an easy handle and register it using this method. 98 */ 99 void registerEasyHandle(CURL *easy) const; 100 101 /** 102 * Use this method to add new Request into manager's queue. 103 * Manager will periodically call handle() method of these 104 * Requests until they set their state to FINISHED. 105 * 106 * If Request's state is RETRY, handleRetry() is called instead. 107 * 108 * The passed callback would be called after Request is deleted. 109 * 110 * @note This method starts the timer if it's not started yet. 111 * 112 * @return the same Request pointer, just as a shortcut 113 */ 114 Request *addRequest(Request *request, RequestCallback callback = nullptr); 115 116 /** Return URL-encoded version of given string. */ 117 Common::String urlEncode(Common::String s) const; 118 119 static uint32 getCloudRequestsPeriodInMicroseconds(); 120 }; 121 122 /** Shortcut for accessing the connection manager. */ 123 #define ConnMan Networking::ConnectionManager::instance() 124 125 } // End of namespace Networking 126 127 #endif 128