Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/Platform.cpp

Issue 29706560: Issue 5179 - Implement asynchronous executor with a controllable lifetime (Closed) Base URL: https://github.com/adblockplus/libadblockplus.git
Patch Set: Created Feb. 23, 2018, 10:29 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 #include <AdblockPlus/Platform.h> 17 #include <AdblockPlus/Platform.h>
18 #include <AdblockPlus/JsEngine.h> 18 #include <AdblockPlus/JsEngine.h>
19 #include <AdblockPlus/FilterEngine.h> 19 #include <AdblockPlus/FilterEngine.h>
20 #include <AdblockPlus/DefaultLogSystem.h> 20 #include <AdblockPlus/DefaultLogSystem.h>
21 #include <AdblockPlus/AsyncExecutor.h>
21 #include "DefaultTimer.h" 22 #include "DefaultTimer.h"
22 #include "DefaultWebRequest.h" 23 #include "DefaultWebRequest.h"
23 #include "DefaultFileSystem.h" 24 #include "DefaultFileSystem.h"
24 #include <stdexcept> 25 #include <stdexcept>
25 26
26 using namespace AdblockPlus; 27 using namespace AdblockPlus;
27 28
28 namespace 29 namespace
29 { 30 {
30 void DummyScheduler(const AdblockPlus::SchedulerTask& task)
31 {
32 std::thread(task).detach();
33 }
34
35 template<typename T> 31 template<typename T>
36 void ValidatePlatformCreationParameter(const std::unique_ptr<T>& param, const char* paramName) 32 void ValidatePlatformCreationParameter(const std::unique_ptr<T>& param, const char* paramName)
37 { 33 {
38 if (!param) 34 if (!param)
39 throw std::logic_error(paramName + std::string(" must not be nullptr")); 35 throw std::logic_error(paramName + std::string(" must not be nullptr"));
40 } 36 }
41 } 37 }
42 38
43 #define ASSIGN_PLATFORM_PARAM(param) ValidatePlatformCreationParameter(param = s td::move(creationParameters.param), #param) 39 #define ASSIGN_PLATFORM_PARAM(param) ValidatePlatformCreationParameter(param = s td::move(creationParameters.param), #param)
44 40
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 } 110 }
115 111
116 void Platform::WithLogSystem(const WithLogSystemCallback& callback) 112 void Platform::WithLogSystem(const WithLogSystemCallback& callback)
117 { 113 {
118 if (logSystem && callback) 114 if (logSystem && callback)
119 callback(*logSystem); 115 callback(*logSystem);
120 } 116 }
121 117
122 namespace 118 namespace
123 { 119 {
120 class SharedAsyncExecutor {
sergei 2018/02/23 11:16:42 It's rather a compatibility thing to simplify the
121 public:
122 SharedAsyncExecutor()
123 : executor(new AsyncExecutor())
124 {
125 }
126 void Dispatch(const std::function<void()>& task) {
127 std::lock_guard<std::mutex> lock(asyncExecutorMutex);
128 if (!executor)
129 return;
130 executor->Dispatch(task);
131 }
132 void Invalidate() {
133 std::unique_ptr<AsyncExecutor> tmp;
sergei 2018/02/23 11:16:42 JIC, it's needed to prevent dead locks. If `execut
134 {
135 std::lock_guard<std::mutex> lock(asyncExecutorMutex);
136 tmp = move(executor);
137 }
138 }
139 private:
140 std::mutex asyncExecutorMutex;
141 std::unique_ptr<AsyncExecutor> executor;
142 };
143
124 class DefaultPlatform : public Platform 144 class DefaultPlatform : public Platform
125 { 145 {
126 public: 146 public:
127 typedef std::shared_ptr<Scheduler> AsyncExecutorPtr; 147 typedef std::shared_ptr<SharedAsyncExecutor> AsyncExecutorPtr;
128 explicit DefaultPlatform(const AsyncExecutorPtr& asyncExecutor, CreationPara meters&& creationParams) 148 explicit DefaultPlatform(const std::shared_ptr<SharedAsyncExecutor>& asyncEx ecutor, CreationParameters&& creationParams)
hub 2018/02/23 22:59:35 Since there is `typedef std::shared_ptr<SharedAsyn
sergei 2018/03/01 11:18:37 Fixed, I somehow forgot about it ))
129 : Platform(std::move(creationParams)), asyncExecutor(asyncExecutor) 149 : Platform(std::move(creationParams)), asyncExecutor(asyncExecutor)
130 { 150 {
131 } 151 }
132 ~DefaultPlatform(); 152 ~DefaultPlatform();
133 153
134 void WithTimer(const WithTimerCallback&) override; 154 void WithTimer(const WithTimerCallback&) override;
135 void WithFileSystem(const WithFileSystemCallback&) override; 155 void WithFileSystem(const WithFileSystemCallback&) override;
136 void WithWebRequest(const WithWebRequestCallback&) override; 156 void WithWebRequest(const WithWebRequestCallback&) override;
137 void WithLogSystem(const WithLogSystemCallback&) override; 157 void WithLogSystem(const WithLogSystemCallback&) override;
138 158
139 private: 159 private:
140 AsyncExecutorPtr asyncExecutor; 160 std::shared_ptr<SharedAsyncExecutor> asyncExecutor;
141 std::recursive_mutex interfacesMutex; 161 std::recursive_mutex interfacesMutex;
142 }; 162 };
143 163
144 DefaultPlatform::~DefaultPlatform() 164 DefaultPlatform::~DefaultPlatform()
145 { 165 {
146 asyncExecutor.reset(); 166 asyncExecutor->Invalidate();
147 LogSystemPtr tmpLogSystem; 167 LogSystemPtr tmpLogSystem;
148 TimerPtr tmpTimer; 168 TimerPtr tmpTimer;
149 FileSystemPtr tmpFileSystem; 169 FileSystemPtr tmpFileSystem;
150 WebRequestPtr tmpWebRequest; 170 WebRequestPtr tmpWebRequest;
151 { 171 {
152 std::lock_guard<std::recursive_mutex> lock(interfacesMutex); 172 std::lock_guard<std::recursive_mutex> lock(interfacesMutex);
153 tmpLogSystem = std::move(logSystem); 173 tmpLogSystem = std::move(logSystem);
154 tmpTimer = std::move(timer); 174 tmpTimer = std::move(timer);
155 tmpFileSystem = std::move(fileSystem); 175 tmpFileSystem = std::move(fileSystem);
156 tmpWebRequest = std::move(webRequest); 176 tmpWebRequest = std::move(webRequest);
(...skipping 20 matching lines...) Expand all
177 197
178 void DefaultPlatform::WithLogSystem(const WithLogSystemCallback& callback) 198 void DefaultPlatform::WithLogSystem(const WithLogSystemCallback& callback)
179 { 199 {
180 std::lock_guard<std::recursive_mutex> lock(interfacesMutex); 200 std::lock_guard<std::recursive_mutex> lock(interfacesMutex);
181 Platform::WithLogSystem(callback); 201 Platform::WithLogSystem(callback);
182 } 202 }
183 } 203 }
184 204
185 Scheduler DefaultPlatformBuilder::GetDefaultAsyncExecutor() 205 Scheduler DefaultPlatformBuilder::GetDefaultAsyncExecutor()
186 { 206 {
187 if (!defaultScheduler)
188 {
189 asyncExecutor = std::make_shared<Scheduler>(::DummyScheduler);
190 std::weak_ptr<Scheduler> weakExecutor = asyncExecutor;
191 defaultScheduler = [weakExecutor](const SchedulerTask& task)
192 {
193 if (auto executor = weakExecutor.lock())
194 {
195 (*executor)(task);
196 }
197 };
198 }
199 return defaultScheduler; 207 return defaultScheduler;
200 } 208 }
201 209
202 void DefaultPlatformBuilder::CreateDefaultTimer() 210 void DefaultPlatformBuilder::CreateDefaultTimer()
203 { 211 {
204 timer.reset(new DefaultTimer()); 212 timer.reset(new DefaultTimer());
205 } 213 }
206 214
207 void DefaultPlatformBuilder::CreateDefaultFileSystem(const std::string& basePath ) 215 void DefaultPlatformBuilder::CreateDefaultFileSystem(const std::string& basePath )
208 { 216 {
209 fileSystem.reset(new DefaultFileSystem(GetDefaultAsyncExecutor(), std::unique_ ptr<DefaultFileSystemSync>(new DefaultFileSystemSync(basePath)))); 217 fileSystem.reset(new DefaultFileSystem(GetDefaultAsyncExecutor(), std::unique_ ptr<DefaultFileSystemSync>(new DefaultFileSystemSync(basePath))));
210 } 218 }
211 219
212 void DefaultPlatformBuilder::CreateDefaultWebRequest(std::unique_ptr<IWebRequest Sync> webRequest) 220 void DefaultPlatformBuilder::CreateDefaultWebRequest(std::unique_ptr<IWebRequest Sync> webRequest)
213 { 221 {
214 if (!webRequest) 222 if (!webRequest)
215 webRequest.reset(new DefaultWebRequestSync()); 223 webRequest.reset(new DefaultWebRequestSync());
216 this->webRequest.reset(new DefaultWebRequest(GetDefaultAsyncExecutor(), std::m ove(webRequest))); 224 this->webRequest.reset(new DefaultWebRequest(GetDefaultAsyncExecutor(), std::m ove(webRequest)));
217 } 225 }
218 226
219 void DefaultPlatformBuilder::CreateDefaultLogSystem() 227 void DefaultPlatformBuilder::CreateDefaultLogSystem()
220 { 228 {
221 logSystem.reset(new DefaultLogSystem()); 229 logSystem.reset(new DefaultLogSystem());
222 } 230 }
223 231
224 std::unique_ptr<Platform> DefaultPlatformBuilder::CreatePlatform() 232 std::unique_ptr<Platform> DefaultPlatformBuilder::CreatePlatform()
225 { 233 {
234 auto sharedAsyncExecutor = std::make_shared<SharedAsyncExecutor>();
235 defaultScheduler = [sharedAsyncExecutor](const SchedulerTask& task)
236 {
237 sharedAsyncExecutor->Dispatch(task);
238 };
226 if (!logSystem) 239 if (!logSystem)
227 CreateDefaultLogSystem(); 240 CreateDefaultLogSystem();
228 if (!timer) 241 if (!timer)
229 CreateDefaultTimer(); 242 CreateDefaultTimer();
230 if (!fileSystem) 243 if (!fileSystem)
231 CreateDefaultFileSystem(); 244 CreateDefaultFileSystem();
232 if (!webRequest) 245 if (!webRequest)
233 CreateDefaultWebRequest(); 246 CreateDefaultWebRequest();
234 247
235 std::unique_ptr<Platform> platform(new DefaultPlatform(asyncExecutor, std::mov e(*this))); 248 std::unique_ptr<Platform> platform(new DefaultPlatform(sharedAsyncExecutor, st d::move(*this)));
236 asyncExecutor.reset();
237 return platform; 249 return platform;
238 } 250 }
OLDNEW

Powered by Google App Engine
This is Rietveld