OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/safe_browsing_db/v4_local_database_manager.h" | 5 #include "components/safe_browsing_db/v4_local_database_manager.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "components/safe_browsing_db/safebrowsing.pb.h" | 9 #include "components/safe_browsing_db/safebrowsing.pb.h" |
10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
11 | 11 |
12 using content::BrowserThread; | 12 using content::BrowserThread; |
13 | 13 |
14 namespace safe_browsing { | 14 namespace safe_browsing { |
15 | 15 |
16 V4LocalDatabaseManager::V4LocalDatabaseManager() : enabled_(false) {} | 16 V4LocalDatabaseManager::V4LocalDatabaseManager(const base::FilePath& base_path) |
17 : base_path_(base_path), | |
18 enabled_(false), | |
19 closing_database_(false) { | |
20 DCHECK(!base_path_.empty()); | |
21 } | |
Scott Hess - ex-Googler
2016/05/09 19:40:39
DCHECK() and closing brace should be undented 4 sp
vakh (use Gerrit instead)
2016/05/11 20:01:27
Done.
| |
17 | 22 |
18 V4LocalDatabaseManager::~V4LocalDatabaseManager() { | 23 V4LocalDatabaseManager::~V4LocalDatabaseManager() { |
19 DCHECK(!enabled_); | 24 DCHECK(!enabled_); |
20 } | 25 } |
21 | 26 |
22 bool V4LocalDatabaseManager::IsSupported() const { | 27 bool V4LocalDatabaseManager::IsSupported() const { |
23 return true; | 28 return true; |
24 } | 29 } |
25 | 30 |
26 safe_browsing::ThreatSource V4LocalDatabaseManager::GetThreatSource() const { | 31 safe_browsing::ThreatSource V4LocalDatabaseManager::GetThreatSource() const { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 // TODO(vakh): Implement this skeleton. | 139 // TODO(vakh): Implement this skeleton. |
135 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 140 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
136 DCHECK(enabled_); | 141 DCHECK(enabled_); |
137 } | 142 } |
138 | 143 |
139 void V4LocalDatabaseManager::StartOnIOThread( | 144 void V4LocalDatabaseManager::StartOnIOThread( |
140 net::URLRequestContextGetter* request_context_getter, | 145 net::URLRequestContextGetter* request_context_getter, |
141 const V4ProtocolConfig& config) { | 146 const V4ProtocolConfig& config) { |
142 SafeBrowsingDatabaseManager::StartOnIOThread(request_context_getter, config); | 147 SafeBrowsingDatabaseManager::StartOnIOThread(request_context_getter, config); |
143 | 148 |
144 #if defined(OS_WIN) || defined (OS_LINUX) || defined (OS_MACOSX) | 149 // Only get a new task runner if there isn't one already. If the service has |
150 // previously been started and stopped, a task runner could already exist. | |
151 if (!task_runner_) { | |
152 base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); | |
153 task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior( | |
154 pool->GetSequenceToken(), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | |
155 } | |
156 | |
157 SetupUpdateProtocolManager(request_context_getter, config); | |
158 | |
159 SetupDatabase(); | |
160 | |
161 enabled_ = true; | |
162 } | |
163 | |
164 void V4LocalDatabaseManager::SetupUpdateProtocolManager( | |
165 net::URLRequestContextGetter* request_context_getter, | |
166 const V4ProtocolConfig& config) { | |
167 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX) | |
145 // TODO(vakh): Remove this if/endif block when the V4Database is implemented. | 168 // TODO(vakh): Remove this if/endif block when the V4Database is implemented. |
146 // Filed as http://crbug.com/608075 | 169 // Filed as http://crbug.com/608075 |
147 UpdateListIdentifier update_list_identifier; | 170 UpdateListIdentifier update_list_identifier; |
148 #if defined(OS_WIN) | 171 #if defined(OS_WIN) |
149 update_list_identifier.platform_type = WINDOWS_PLATFORM; | 172 update_list_identifier.platform_type = WINDOWS_PLATFORM; |
150 #elif defined (OS_LINUX) | 173 #elif defined(OS_LINUX) |
151 update_list_identifier.platform_type = LINUX_PLATFORM; | 174 update_list_identifier.platform_type = LINUX_PLATFORM; |
152 #else | 175 #else |
153 update_list_identifier.platform_type = OSX_PLATFORM; | 176 update_list_identifier.platform_type = OSX_PLATFORM; |
154 #endif | 177 #endif |
155 update_list_identifier.threat_entry_type = URL_EXPRESSION; | 178 update_list_identifier.threat_entry_type = URL_EXPRESSION; |
156 update_list_identifier.threat_type = MALWARE_THREAT; | 179 update_list_identifier.threat_type = MALWARE_THREAT; |
157 current_list_states_[update_list_identifier] = ""; | 180 current_list_states_[update_list_identifier] = ""; |
158 #endif | 181 #endif |
159 | 182 |
160 V4UpdateCallback callback = base::Bind( | 183 V4UpdateCallback callback = base::Bind( |
161 &V4LocalDatabaseManager::UpdateRequestCompleted, base::Unretained(this)); | 184 &V4LocalDatabaseManager::UpdateRequestCompleted, base::Unretained(this)); |
185 | |
162 v4_update_protocol_manager_ = V4UpdateProtocolManager::Create( | 186 v4_update_protocol_manager_ = V4UpdateProtocolManager::Create( |
163 request_context_getter, config, current_list_states_, callback); | 187 request_context_getter, config, current_list_states_, callback); |
188 } | |
164 | 189 |
165 enabled_ = true; | 190 bool V4LocalDatabaseManager::DatabaseAvailable() const { |
191 base::AutoLock lock(database_lock_); | |
192 return !closing_database_ && v4_database_.get(); | |
193 } | |
194 | |
195 void V4LocalDatabaseManager::SetupDatabase() { | |
196 DCHECK(task_runner_); | |
197 DCHECK(!base_path_.empty()); | |
198 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
199 | |
200 if (DatabaseAvailable()) | |
201 return; | |
202 | |
203 // TODO(vakh): list_info_map should probably be a hard-coded map. | |
204 ListInfoMap list_info_map; | |
205 | |
206 // Acquiring the lock here guarantees correct ordering between the writes to | |
207 // the database object across threads. | |
208 base::AutoLock lock(database_lock_); | |
209 v4_database_.reset( | |
210 V4Database::Create(task_runner_, base_path_, list_info_map)); | |
166 } | 211 } |
167 | 212 |
168 void V4LocalDatabaseManager::StopOnIOThread(bool shutdown) { | 213 void V4LocalDatabaseManager::StopOnIOThread(bool shutdown) { |
169 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 214 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
170 | 215 |
216 enabled_ = false; | |
217 | |
171 // Delete the V4UpdateProtocolManager. | 218 // Delete the V4UpdateProtocolManager. |
172 // This cancels any in-flight update request. | 219 // This cancels any in-flight update request. |
173 if (v4_update_protocol_manager_.get()) { | 220 if (v4_update_protocol_manager_.get()) { |
174 v4_update_protocol_manager_.reset(); | 221 v4_update_protocol_manager_.reset(); |
175 } | 222 } |
176 | 223 |
177 enabled_ = false; | 224 // Close the database. Cases to avoid: |
225 // * If |closing_database_| is true, continuing will queue up a second | |
226 // request, |closing_database_| will be reset after handling the first | |
227 // request, and if any functions on the db thread recreate the database, we | |
228 // could start using it on the IO thread and then have the second request | |
229 // handler delete it out from under us. | |
230 // * If |v4_database_| isn't set, then either no creation request is in | |
231 // flight, in which case we don't need to do anything, or one is in flight, | |
232 // in which case the database will be recreated before our deletion request | |
233 // is handled, and could be used on the IO thread in that time period, | |
234 // leading to the same problem as above. | |
235 // Checking DatabaseAvailable() avoids both of these. | |
236 if (DatabaseAvailable()) { | |
237 closing_database_ = true; | |
Scott Hess - ex-Googler
2016/05/09 19:40:39
Before I dig in and ponder things like "OMG, can't
Scott Hess - ex-Googler
2016/05/09 20:28:08
Too late! Already pondered!
The original source
vakh (use Gerrit instead)
2016/05/09 20:32:25
Scott, you're right that some of this code, such a
vakh (use Gerrit instead)
2016/05/09 20:34:29
Sounds good. I'll look into this.
My understanding
| |
238 | |
239 // Scheduling it as a task instead of doing this right away since this may | |
240 // be a long operation (closing stores, writing to disk, etc.) | |
241 task_runner_->PostTask( | |
242 FROM_HERE, base::Bind(&V4LocalDatabaseManager::OnCloseDatabase, this)); | |
243 } | |
244 | |
178 SafeBrowsingDatabaseManager::StopOnIOThread(shutdown); | 245 SafeBrowsingDatabaseManager::StopOnIOThread(shutdown); |
179 } | 246 } |
180 | 247 |
248 void V4LocalDatabaseManager::OnCloseDatabase() { | |
249 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
250 DCHECK(closing_database_); | |
251 | |
252 // Acquiring the lock here guarantees correct ordering between the resetting | |
253 // of |v4_database_| and of |closing_database_|, which ensures there won't | |
254 // be a window during which the IO thread falsely believes the database is | |
255 // available. | |
256 base::AutoLock lock(database_lock_); | |
257 | |
258 // Because |closing_database_| is true, nothing on the IO thread will be | |
259 // accessing the database, so it's safe to reset. | |
260 v4_database_.reset(); | |
261 | |
262 closing_database_ = false; | |
263 } | |
264 | |
181 void V4LocalDatabaseManager::UpdateRequestCompleted( | 265 void V4LocalDatabaseManager::UpdateRequestCompleted( |
182 const std::vector<ListUpdateResponse>& responses) { | 266 const std::vector<ListUpdateResponse>& responses) { |
183 // TODO(vakh): Updates downloaded. Store them on disk and record new state. | 267 // TODO(vakh): Updates downloaded. Store them on disk and record new state. |
184 } | 268 } |
185 | 269 |
186 } // namespace safe_browsing | 270 } // namespace safe_browsing |
OLD | NEW |