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 = 25; 42 static const uint32 TIMER_INTERVAL = 1000000 / FRAMES_PER_SECOND; 43 static const uint32 CLOUD_PERIOD = 1; //every frame 44 static const uint32 CURL_PERIOD = 1; //every frame 45 static const uint32 DEBUG_PRINT_PERIOD = FRAMES_PER_SECOND; // once per second 46 47 friend void connectionsThread(void *); //calls handle() 48 49 typedef Common::BaseCallback<Request *> *RequestCallback; 50 51 /** 52 * RequestWithCallback is used by ConnectionManager to 53 * storage the Request and a callback which should be 54 * called on Request delete. 55 * 56 * Usually one won't need to pass such callback, but 57 * in some cases you'd like to know whether Request is 58 * still running. 59 * 60 * For example, Cloud::Storage is keeping track of how 61 * many Requests are running, and thus it needs to know 62 * that Request was destroyed to decrease its counter. 63 * 64 * onDeleteCallback is called with *invalid* pointer. 65 * ConnectionManager deletes Request first and then passes 66 * the pointer to the callback. One may use the address 67 * to find it in own HashMap or Array and remove it. 68 * So, again, this pointer is for information only. One 69 * cannot use it. 70 */ 71 struct RequestWithCallback { 72 Request *request; 73 RequestCallback onDeleteCallback; 74 requestRequestWithCallback75 RequestWithCallback(Request *rq = nullptr, RequestCallback cb = nullptr): request(rq), onDeleteCallback(cb) {} 76 }; 77 78 CURLM *_multi; 79 bool _timerStarted; 80 Common::Array<RequestWithCallback> _requests, _addedRequests; 81 Common::Mutex _handleMutex, _addedRequestsMutex; 82 uint32 _frame; 83 84 void startTimer(int interval = TIMER_INTERVAL); 85 void stopTimer(); 86 void handle(); 87 void interateRequests(); 88 void processTransfers(); 89 bool hasAddedRequests(); 90 91 public: 92 ConnectionManager(); 93 virtual ~ConnectionManager(); 94 95 /** 96 * All libcurl transfers are going through this ConnectionManager. 97 * So, if you want to start any libcurl transfer, you must create 98 * an easy handle and register it using this method. 99 */ 100 void registerEasyHandle(CURL *easy) const; 101 102 /** 103 * Use this method to add new Request into manager's queue. 104 * Manager will periodically call handle() method of these 105 * Requests until they set their state to FINISHED. 106 * 107 * If Request's state is RETRY, handleRetry() is called instead. 108 * 109 * The passed callback would be called after Request is deleted. 110 * 111 * @note This method starts the timer if it's not started yet. 112 * 113 * @return the same Request pointer, just as a shortcut 114 */ 115 Request *addRequest(Request *request, RequestCallback callback = nullptr); 116 117 /** Return URL-encoded version of given string. */ 118 Common::String urlEncode(Common::String s) const; 119 120 static uint32 getCloudRequestsPeriodInMicroseconds(); 121 122 /** Return the path to the CA certificates bundle. */ 123 static const char *getCaCertPath(); 124 }; 125 126 /** Shortcut for accessing the connection manager. */ 127 #define ConnMan Networking::ConnectionManager::instance() 128 129 } // End of namespace Networking 130 131 #endif 132