Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: components/safe_browsing_db/v4_database.cc

Issue 2062013002: Fetch incremental updates. Store new state in V4Store. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nit: Use base::SStringPrintf instead of string concat Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <memory> 5 #include <memory>
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/debug/leak_annotations.h" 8 #include "base/debug/leak_annotations.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "components/safe_browsing_db/v4_database.h" 11 #include "components/safe_browsing_db/v4_database.h"
12 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
13 13
14 using content::BrowserThread; 14 using content::BrowserThread;
15 15
16 namespace safe_browsing { 16 namespace safe_browsing {
17 17
18 // static 18 // static
19 V4StoreFactory* V4Database::factory_ = NULL; 19 V4StoreFactory* V4Database::factory_ = NULL;
20 20
21 // static 21 // static
22 void V4Database::Create( 22 bool V4Database::Create(
23 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, 23 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
24 const base::FilePath& base_path, 24 const base::FilePath& base_path,
25 const ListInfoMap& list_info_map, 25 const StoreFileNameMap& store_file_name_map,
26 NewDatabaseReadyCallback callback) { 26 DatabaseUpdatedCallback db_updated_callback,
27 NewDatabaseReadyCallback new_db_callback) {
27 // Create the database, which may be a lengthy operation, on the 28 // Create the database, which may be a lengthy operation, on the
28 // db_task_runner, but once that is done, call the caller back on this 29 // db_task_runner, but once that is done, call the caller back on this
29 // thread. 30 // thread.
31 if (!base_path.IsAbsolute() || store_file_name_map.empty()) {
Nathan Parker 2016/06/15 21:24:11 Could just dcheck on these, and then the caller do
vakh (use Gerrit instead) 2016/06/16 01:07:34 Done.
32 return false;
33 }
34
30 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner = 35 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner =
31 base::MessageLoop::current()->task_runner(); 36 base::MessageLoop::current()->task_runner();
32 db_task_runner->PostTask( 37 db_task_runner->PostTask(
33 FROM_HERE, 38 FROM_HERE, base::Bind(&V4Database::CreateOnTaskRunner, db_task_runner,
34 base::Bind(&V4Database::CreateOnTaskRunner, db_task_runner, base_path, 39 base_path, store_file_name_map, db_updated_callback,
35 list_info_map, callback_task_runner, callback)); 40 callback_task_runner, new_db_callback));
41 return true;
36 } 42 }
37 43
38 // static 44 // static
39 void V4Database::CreateOnTaskRunner( 45 void V4Database::CreateOnTaskRunner(
40 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, 46 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
41 const base::FilePath& base_path, 47 const base::FilePath& base_path,
42 const ListInfoMap& list_info_map, 48 const StoreFileNameMap& store_file_name_map,
49 DatabaseUpdatedCallback db_updated_callback,
43 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner, 50 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner,
44 NewDatabaseReadyCallback callback) { 51 NewDatabaseReadyCallback new_db_callback) {
45 DCHECK(db_task_runner->RunsTasksOnCurrentThread()); 52 DCHECK(db_task_runner->RunsTasksOnCurrentThread());
46 DCHECK(base_path.IsAbsolute());
47 53
48 if (!factory_) { 54 if (!factory_) {
49 factory_ = new V4StoreFactory(); 55 factory_ = new V4StoreFactory();
50 ANNOTATE_LEAKING_OBJECT_PTR(factory_); 56 ANNOTATE_LEAKING_OBJECT_PTR(factory_);
51 } 57 }
52 auto store_map = base::MakeUnique<StoreMap>(); 58 auto store_map = base::MakeUnique<StoreMap>();
53 for (const auto& list_info : list_info_map) { 59 for (const auto& store_info : store_file_name_map) {
54 const UpdateListIdentifier& update_list_identifier = list_info.first; 60 const UpdateListIdentifier& update_list_identifier = store_info.first;
55 const base::FilePath store_path = base_path.AppendASCII(list_info.second); 61 const base::FilePath store_path = base_path.AppendASCII(store_info.second);
56 (*store_map)[update_list_identifier].reset( 62 (*store_map)[update_list_identifier].reset(
57 factory_->CreateV4Store(db_task_runner, store_path)); 63 factory_->CreateV4Store(db_task_runner, store_path));
58 } 64 }
59 std::unique_ptr<V4Database> v4_database( 65 std::unique_ptr<V4Database> v4_database(new V4Database(
60 new V4Database(db_task_runner, std::move(store_map))); 66 db_task_runner, std::move(store_map), db_updated_callback));
61 67
62 // Database is done loading, pass it to the callback on the caller's thread. 68 // Database is done loading, pass it to the new_db_callback on the caller's
69 // thread.
63 callback_task_runner->PostTask( 70 callback_task_runner->PostTask(
64 FROM_HERE, base::Bind(callback, base::Passed(&v4_database))); 71 FROM_HERE, base::Bind(new_db_callback, base::Passed(&v4_database)));
65 } 72 }
66 73
67 V4Database::V4Database( 74 V4Database::V4Database(
68 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, 75 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
69 std::unique_ptr<StoreMap> store_map) 76 std::unique_ptr<StoreMap> store_map,
70 : db_task_runner_(db_task_runner), store_map_(std::move(store_map)) { 77 DatabaseUpdatedCallback db_updated_callback)
78 : db_task_runner_(db_task_runner),
79 store_map_(std::move(store_map)),
80 store_state_map_(base::MakeUnique<StoreStateMap>()),
81 db_updated_callback_(db_updated_callback),
82 pending_store_updates_(0) {
71 DCHECK(db_task_runner->RunsTasksOnCurrentThread()); 83 DCHECK(db_task_runner->RunsTasksOnCurrentThread());
84 UpdateStoreStateMap();
72 // TODO(vakh): Implement skeleton 85 // TODO(vakh): Implement skeleton
73 } 86 }
74 87
75 // static 88 // static
76 void V4Database::Destroy(std::unique_ptr<V4Database> v4_database) { 89 void V4Database::Destroy(std::unique_ptr<V4Database> v4_database) {
77 V4Database* v4_database_raw = v4_database.release(); 90 V4Database* v4_database_raw = v4_database.release();
78 if (v4_database_raw) { 91 if (v4_database_raw) {
79 v4_database_raw->db_task_runner_->DeleteSoon(FROM_HERE, v4_database_raw); 92 v4_database_raw->db_task_runner_->DeleteSoon(FROM_HERE, v4_database_raw);
80 } 93 }
81 } 94 }
82 95
83 V4Database::~V4Database() { 96 V4Database::~V4Database() {
84 DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); 97 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
85 } 98 }
86 99
100 void V4Database::ApplyUpdate(const std::vector<ListUpdateResponse>& responses) {
101 DCHECK_CURRENTLY_ON(BrowserThread::IO);
102 DCHECK(!pending_store_updates_);
103
104 // Post the V4Store update task on the task runner but get the callback on the
105 // current thread (IO thread).
106 const scoped_refptr<base::SingleThreadTaskRunner>& current_task_runner =
107 base::MessageLoop::current()->task_runner();
108 for (const auto& response : responses) {
109 UpdateListIdentifier identifier(response);
110 StoreMap::const_iterator iter = store_map_->find(identifier);
111 if (iter != store_map_->end()) {
112 const auto& old_store = iter->second;
113 if (old_store->state() != response.new_client_state()) {
114 // A different state implies there are updates to process.
115 UpdatedStoreReadyCallback store_ready_callback = base::Bind(
116 &V4Database::UpdatedStoreReady, base::Unretained(this), identifier);
117 db_task_runner_->PostTask(
Nathan Parker 2016/06/15 21:24:11 Increment before posting, since otherwise the post
vakh (use Gerrit instead) 2016/06/16 01:07:34 Done. Though that's not a problem since the synchr
118 FROM_HERE,
119 base::Bind(&V4Store::ApplyUpdate, base::Unretained(old_store.get()),
120 response, current_task_runner, store_ready_callback));
121 pending_store_updates_++;
122 }
123 } else {
124 DVLOG(1) << "Got update for unexpected identifier: " << identifier;
Nathan Parker 2016/06/15 21:24:12 I'd say this is more severe, and could be a DCHECK
vakh (use Gerrit instead) 2016/06/16 01:07:35 Done.
125 }
126 }
127
128 if (!pending_store_updates_) {
129 db_updated_callback_.Run();
130 }
131 }
132
133 void V4Database::UpdatedStoreReady(UpdateListIdentifier identifier,
134 std::unique_ptr<V4Store> new_store) {
135 DCHECK_CURRENTLY_ON(BrowserThread::IO);
136 DCHECK(pending_store_updates_);
137 (*store_state_map_)[identifier] = new_store->state();
138 (*store_map_)[identifier] = std::move(new_store);
139
140 // Since this method is always called on the IO thread, there can't be a race
141 // condition in decrementing pending_store_updates_.
142 pending_store_updates_--;
143 if (!pending_store_updates_) {
144 db_updated_callback_.Run();
145 }
146 }
147
87 bool V4Database::ResetDatabase() { 148 bool V4Database::ResetDatabase() {
88 DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); 149 DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
89 bool reset_success = true; 150 bool reset_success = true;
90 for (const auto& store_id_and_store : *store_map_) { 151 for (const auto& store_map_iter : *store_map_) {
91 if (!store_id_and_store.second->Reset()) { 152 if (!store_map_iter.second->Reset()) {
92 reset_success = false; 153 reset_success = false;
93 } 154 }
94 } 155 }
95 return reset_success; 156 return reset_success;
96 } 157 }
97 158
159 void V4Database::UpdateStoreStateMap() {
160 for (const auto& store_map_iter : *store_map_) {
161 (*store_state_map_)[store_map_iter.first] = store_map_iter.second->state();
Nathan Parker 2016/06/15 21:24:13 I'm confused: is the store_state_map just a view i
vakh (use Gerrit instead) 2016/06/16 01:07:35 Yes, it is a view. If we do not have a store_state
Nathan Parker 2016/06/17 21:34:19 What if you created this map on the heap only when
vakh (use Gerrit instead) 2016/06/21 00:29:36 Done. See patch 10.
162 }
163 }
164
98 } // namespace safe_browsing 165 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698