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

Side by Side Diff: content/browser/indexed_db/indexed_db_dispatcher_host.cc

Issue 2727733004: [IndexedDB] Closing mojo connections when renderer quits (Closed)
Patch Set: fix and rebase Created 3 years, 8 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/indexed_db/indexed_db_dispatcher_host.h" 5 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/guid.h" 9 #include "base/guid.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/process/process.h" 11 #include "base/process/process.h"
12 #include "base/sequenced_task_runner.h"
12 #include "base/stl_util.h" 13 #include "base/stl_util.h"
13 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
14 #include "content/browser/indexed_db/indexed_db_callbacks.h" 15 #include "content/browser/indexed_db/indexed_db_callbacks.h"
15 #include "content/browser/indexed_db/indexed_db_connection.h" 16 #include "content/browser/indexed_db/indexed_db_connection.h"
16 #include "content/browser/indexed_db/indexed_db_context_impl.h" 17 #include "content/browser/indexed_db/indexed_db_context_impl.h"
17 #include "content/browser/indexed_db/indexed_db_database_callbacks.h" 18 #include "content/browser/indexed_db/indexed_db_database_callbacks.h"
18 #include "content/browser/indexed_db/indexed_db_pending_connection.h" 19 #include "content/browser/indexed_db/indexed_db_pending_connection.h"
19 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
20 #include "storage/browser/blob/blob_data_builder.h" 21 #include "storage/browser/blob/blob_data_builder.h"
21 #include "storage/browser/blob/blob_storage_context.h" 22 #include "storage/browser/blob/blob_storage_context.h"
22 #include "storage/browser/database/database_util.h" 23 #include "storage/browser/database/database_util.h"
23 #include "url/origin.h" 24 #include "url/origin.h"
24 25
25 namespace content { 26 namespace content {
26 27
27 namespace { 28 namespace {
28 29
29 const char kInvalidOrigin[] = "Origin is invalid"; 30 const char kInvalidOrigin[] = "Origin is invalid";
30 31
31 bool IsValidOrigin(const url::Origin& origin) { 32 bool IsValidOrigin(const url::Origin& origin) {
32 return !origin.unique(); 33 return !origin.unique();
33 } 34 }
34 35
35 } // namespace 36 } // namespace
36 37
38 class IndexedDBDispatcherHost::IDBThreadHelper {
39 public:
40 IDBThreadHelper(
41 int ipc_process_id,
42 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
43 scoped_refptr<IndexedDBContextImpl> indexed_db_context)
44 : ipc_process_id_(ipc_process_id),
45 request_context_getter_(std::move(request_context_getter)),
46 indexed_db_context_(std::move(indexed_db_context)) {}
47 ~IDBThreadHelper() {}
48
49 void GetDatabaseNamesOnIDBThread(scoped_refptr<IndexedDBCallbacks> callbacks,
50 const url::Origin& origin);
51 void OpenOnIDBThread(
52 scoped_refptr<IndexedDBCallbacks> callbacks,
53 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
54 const url::Origin& origin,
55 const base::string16& name,
56 int64_t version,
57 int64_t transaction_id);
58 void DeleteDatabaseOnIDBThread(scoped_refptr<IndexedDBCallbacks> callbacks,
59 const url::Origin& origin,
60 const base::string16& name,
61 bool force_close);
62
63 private:
64 const int ipc_process_id_;
65 scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
66 scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
67
68 DISALLOW_COPY_AND_ASSIGN(IDBThreadHelper);
69 };
70
37 IndexedDBDispatcherHost::IndexedDBDispatcherHost( 71 IndexedDBDispatcherHost::IndexedDBDispatcherHost(
38 int ipc_process_id, 72 int ipc_process_id,
39 net::URLRequestContextGetter* request_context_getter, 73 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
40 IndexedDBContextImpl* indexed_db_context, 74 scoped_refptr<IndexedDBContextImpl> indexed_db_context,
41 ChromeBlobStorageContext* blob_storage_context) 75 scoped_refptr<ChromeBlobStorageContext> blob_storage_context)
42 : request_context_getter_(request_context_getter), 76 : indexed_db_context_(std::move(indexed_db_context)),
43 indexed_db_context_(indexed_db_context), 77 blob_storage_context_(std::move(blob_storage_context)),
44 blob_storage_context_(blob_storage_context), 78 idb_runner_(indexed_db_context_->TaskRunner()),
45 ipc_process_id_(ipc_process_id) { 79 ipc_process_id_(ipc_process_id),
80
jsbell 2017/04/11 16:58:04 nit: remove extra blank line
dmurph 2017/04/11 19:32:49 Done.
81 weak_factory_(this) {
82 idb_helper_ = idb_runner_
jsbell 2017/04/11 16:58:04 When will idb_runner_ be null? Some unit tests?
dmurph 2017/04/11 19:32:49 Yes, unit tests.
83 ? new IDBThreadHelper(ipc_process_id_,
84 std::move(request_context_getter),
85 indexed_db_context_)
86 : nullptr;
46 DCHECK(indexed_db_context_.get()); 87 DCHECK(indexed_db_context_.get());
47 } 88 }
48 89
49 IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {} 90 IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {
91 if (idb_helper_)
92 idb_runner_->DeleteSoon(FROM_HERE, idb_helper_);
93 }
50 94
51 void IndexedDBDispatcherHost::AddBinding( 95 void IndexedDBDispatcherHost::AddBinding(
52 ::indexed_db::mojom::FactoryAssociatedRequest request) { 96 ::indexed_db::mojom::FactoryAssociatedRequest request) {
53 bindings_.AddBinding(this, std::move(request)); 97 bindings_.AddBinding(this, std::move(request));
54 } 98 }
55 99
100 void IndexedDBDispatcherHost::AddDatabaseBinding(
101 std::unique_ptr<::indexed_db::mojom::Database> database,
102 ::indexed_db::mojom::DatabaseAssociatedRequest request) {
103 database_bindings_.AddBinding(std::move(database), std::move(request));
104 }
105
106 void IndexedDBDispatcherHost::AddCursorBinding(
107 std::unique_ptr<::indexed_db::mojom::Cursor> cursor,
108 ::indexed_db::mojom::CursorAssociatedRequest request) {
109 cursor_bindings_.AddBinding(std::move(cursor), std::move(request));
110 }
111
56 std::string IndexedDBDispatcherHost::HoldBlobData( 112 std::string IndexedDBDispatcherHost::HoldBlobData(
57 const IndexedDBBlobInfo& blob_info) { 113 const IndexedDBBlobInfo& blob_info) {
58 DCHECK_CURRENTLY_ON(BrowserThread::IO); 114 DCHECK_CURRENTLY_ON(BrowserThread::IO);
59 std::string uuid = blob_info.uuid(); 115 std::string uuid = blob_info.uuid();
60 storage::BlobStorageContext* context = blob_storage_context_->context(); 116 storage::BlobStorageContext* context = blob_storage_context_->context();
61 std::unique_ptr<storage::BlobDataHandle> blob_data_handle; 117 std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
62 if (uuid.empty()) { 118 if (uuid.empty()) {
63 uuid = base::GenerateGUID(); 119 uuid = base::GenerateGUID();
64 storage::BlobDataBuilder blob_data_builder(uuid); 120 storage::BlobDataBuilder blob_data_builder(uuid);
65 blob_data_builder.set_content_type(base::UTF16ToUTF8(blob_info.type())); 121 blob_data_builder.set_content_type(base::UTF16ToUTF8(blob_info.type()));
(...skipping 22 matching lines...) Expand all
88 return; 144 return;
89 } 145 }
90 146
91 DCHECK_GE(iter->second.second, 1); 147 DCHECK_GE(iter->second.second, 1);
92 if (iter->second.second == 1) 148 if (iter->second.second == 1)
93 blob_data_handle_map_.erase(iter); 149 blob_data_handle_map_.erase(iter);
94 else 150 else
95 --iter->second.second; 151 --iter->second.second;
96 } 152 }
97 153
154 void IndexedDBDispatcherHost::RenderProcessExited(
155 RenderProcessHost* host,
156 base::TerminationStatus status,
157 int exit_code) {
158 BrowserThread::PostTask(
159 BrowserThread::IO, FROM_HERE,
160 base::Bind(&IndexedDBDispatcherHost::InvalidateWeakPtrsAndClearBindings,
161 base::Unretained(this)));
162 }
163
98 void IndexedDBDispatcherHost::GetDatabaseNames( 164 void IndexedDBDispatcherHost::GetDatabaseNames(
99 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info, 165 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info,
100 const url::Origin& origin) { 166 const url::Origin& origin) {
101 DCHECK_CURRENTLY_ON(BrowserThread::IO); 167 DCHECK_CURRENTLY_ON(BrowserThread::IO);
102 168
103 if (!IsValidOrigin(origin)) { 169 if (!IsValidOrigin(origin)) {
104 mojo::ReportBadMessage(kInvalidOrigin); 170 mojo::ReportBadMessage(kInvalidOrigin);
105 return; 171 return;
106 } 172 }
107 173
108 scoped_refptr<IndexedDBCallbacks> callbacks( 174 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
109 new IndexedDBCallbacks(this, origin, std::move(callbacks_info))); 175 this->AsWeakPtr(), origin, std::move(callbacks_info), idb_runner_));
110 indexed_db_context_->TaskRunner()->PostTask( 176 idb_runner_->PostTask(
111 FROM_HERE, 177 FROM_HERE, base::Bind(&IDBThreadHelper::GetDatabaseNamesOnIDBThread,
112 base::Bind(&IndexedDBDispatcherHost::GetDatabaseNamesOnIDBThread, this, 178 base::Unretained(idb_helper_),
113 base::Passed(&callbacks), origin)); 179 base::Passed(&callbacks), origin));
114 } 180 }
115 181
116 void IndexedDBDispatcherHost::Open( 182 void IndexedDBDispatcherHost::Open(
117 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info, 183 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info,
118 ::indexed_db::mojom::DatabaseCallbacksAssociatedPtrInfo 184 ::indexed_db::mojom::DatabaseCallbacksAssociatedPtrInfo
119 database_callbacks_info, 185 database_callbacks_info,
120 const url::Origin& origin, 186 const url::Origin& origin,
121 const base::string16& name, 187 const base::string16& name,
122 int64_t version, 188 int64_t version,
123 int64_t transaction_id) { 189 int64_t transaction_id) {
124 DCHECK_CURRENTLY_ON(BrowserThread::IO); 190 DCHECK_CURRENTLY_ON(BrowserThread::IO);
125 191
126 if (!IsValidOrigin(origin)) { 192 if (!IsValidOrigin(origin)) {
127 mojo::ReportBadMessage(kInvalidOrigin); 193 mojo::ReportBadMessage(kInvalidOrigin);
128 return; 194 return;
129 } 195 }
130 196
131 scoped_refptr<IndexedDBCallbacks> callbacks( 197 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
132 new IndexedDBCallbacks(this, origin, std::move(callbacks_info))); 198 this->AsWeakPtr(), origin, std::move(callbacks_info), idb_runner_));
133 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks( 199 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks(
134 new IndexedDBDatabaseCallbacks(this, std::move(database_callbacks_info))); 200 new IndexedDBDatabaseCallbacks(indexed_db_context_,
135 indexed_db_context_->TaskRunner()->PostTask( 201 std::move(database_callbacks_info)));
202 idb_runner_->PostTask(
136 FROM_HERE, 203 FROM_HERE,
137 base::Bind(&IndexedDBDispatcherHost::OpenOnIDBThread, this, 204 base::Bind(&IDBThreadHelper::OpenOnIDBThread,
138 base::Passed(&callbacks), base::Passed(&database_callbacks), 205 base::Unretained(idb_helper_), base::Passed(&callbacks),
139 origin, name, version, transaction_id)); 206 base::Passed(&database_callbacks), origin, name, version,
207 transaction_id));
140 } 208 }
141 209
142 void IndexedDBDispatcherHost::DeleteDatabase( 210 void IndexedDBDispatcherHost::DeleteDatabase(
143 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info, 211 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info,
144 const url::Origin& origin, 212 const url::Origin& origin,
145 const base::string16& name, 213 const base::string16& name,
146 bool force_close) { 214 bool force_close) {
147 DCHECK_CURRENTLY_ON(BrowserThread::IO); 215 DCHECK_CURRENTLY_ON(BrowserThread::IO);
148 216
149 if (!IsValidOrigin(origin)) { 217 if (!IsValidOrigin(origin)) {
150 mojo::ReportBadMessage(kInvalidOrigin); 218 mojo::ReportBadMessage(kInvalidOrigin);
151 return; 219 return;
152 } 220 }
153 221
154 scoped_refptr<IndexedDBCallbacks> callbacks( 222 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
155 new IndexedDBCallbacks(this, origin, std::move(callbacks_info))); 223 this->AsWeakPtr(), origin, std::move(callbacks_info), idb_runner_));
156 indexed_db_context_->TaskRunner()->PostTask( 224 idb_runner_->PostTask(
157 FROM_HERE, base::Bind(&IndexedDBDispatcherHost::DeleteDatabaseOnIDBThread, 225 FROM_HERE,
158 this, base::Passed(&callbacks), origin, name, 226 base::Bind(&IDBThreadHelper::DeleteDatabaseOnIDBThread,
159 force_close)); 227 base::Unretained(idb_helper_), base::Passed(&callbacks),
228 origin, name, force_close));
160 } 229 }
161 230
162 void IndexedDBDispatcherHost::GetDatabaseNamesOnIDBThread( 231 void IndexedDBDispatcherHost::InvalidateWeakPtrsAndClearBindings() {
232 weak_factory_.InvalidateWeakPtrs();
233 cursor_bindings_.CloseAllBindings();
234 database_bindings_.CloseAllBindings();
235 }
236
237 void IndexedDBDispatcherHost::IDBThreadHelper::GetDatabaseNamesOnIDBThread(
163 scoped_refptr<IndexedDBCallbacks> callbacks, 238 scoped_refptr<IndexedDBCallbacks> callbacks,
164 const url::Origin& origin) { 239 const url::Origin& origin) {
165 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 240 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
166 241
167 base::FilePath indexed_db_path = indexed_db_context_->data_path(); 242 base::FilePath indexed_db_path = indexed_db_context_->data_path();
168 context()->GetIDBFactory()->GetDatabaseNames( 243 indexed_db_context_->GetIDBFactory()->GetDatabaseNames(
169 callbacks, origin, indexed_db_path, request_context_getter_); 244 callbacks, origin, indexed_db_path, request_context_getter_);
170 } 245 }
171 246
172 void IndexedDBDispatcherHost::OpenOnIDBThread( 247 void IndexedDBDispatcherHost::IDBThreadHelper::OpenOnIDBThread(
173 scoped_refptr<IndexedDBCallbacks> callbacks, 248 scoped_refptr<IndexedDBCallbacks> callbacks,
174 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, 249 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
175 const url::Origin& origin, 250 const url::Origin& origin,
176 const base::string16& name, 251 const base::string16& name,
177 int64_t version, 252 int64_t version,
178 int64_t transaction_id) { 253 int64_t transaction_id) {
179 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 254 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
180 255
181 base::TimeTicks begin_time = base::TimeTicks::Now(); 256 base::TimeTicks begin_time = base::TimeTicks::Now();
182 base::FilePath indexed_db_path = indexed_db_context_->data_path(); 257 base::FilePath indexed_db_path = indexed_db_context_->data_path();
183 258
184 // TODO(dgrogan): Don't let a non-existing database be opened (and therefore 259 // TODO(dgrogan): Don't let a non-existing database be opened (and therefore
185 // created) if this origin is already over quota. 260 // created) if this origin is already over quota.
186 callbacks->SetConnectionOpenStartTime(begin_time); 261 callbacks->SetConnectionOpenStartTime(begin_time);
187 std::unique_ptr<IndexedDBPendingConnection> connection = 262 std::unique_ptr<IndexedDBPendingConnection> connection =
188 base::MakeUnique<IndexedDBPendingConnection>( 263 base::MakeUnique<IndexedDBPendingConnection>(
189 callbacks, database_callbacks, ipc_process_id_, transaction_id, 264 callbacks, database_callbacks, ipc_process_id_, transaction_id,
190 version); 265 version);
191 DCHECK(request_context_getter_); 266 DCHECK(request_context_getter_);
192 context()->GetIDBFactory()->Open(name, std::move(connection), 267 indexed_db_context_->GetIDBFactory()->Open(name, std::move(connection),
193 request_context_getter_, origin, 268 request_context_getter_, origin,
194 indexed_db_path); 269 indexed_db_path);
195 } 270 }
196 271
197 void IndexedDBDispatcherHost::DeleteDatabaseOnIDBThread( 272 void IndexedDBDispatcherHost::IDBThreadHelper::DeleteDatabaseOnIDBThread(
198 scoped_refptr<IndexedDBCallbacks> callbacks, 273 scoped_refptr<IndexedDBCallbacks> callbacks,
199 const url::Origin& origin, 274 const url::Origin& origin,
200 const base::string16& name, 275 const base::string16& name,
201 bool force_close) { 276 bool force_close) {
202 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 277 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
203 278
204 base::FilePath indexed_db_path = indexed_db_context_->data_path(); 279 base::FilePath indexed_db_path = indexed_db_context_->data_path();
205 DCHECK(request_context_getter_); 280 DCHECK(request_context_getter_);
206 context()->GetIDBFactory()->DeleteDatabase( 281 indexed_db_context_->GetIDBFactory()->DeleteDatabase(
207 name, request_context_getter_, callbacks, origin, indexed_db_path, 282 name, request_context_getter_, callbacks, origin, indexed_db_path,
208 force_close); 283 force_close);
209 } 284 }
210 285
211 } // namespace content 286 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698