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

Side by Side Diff: content/browser/indexed_db/indexed_db_callbacks.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_callbacks.h" 5 #include "content/browser/indexed_db/indexed_db_callbacks.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory>
10 #include <utility> 11 #include <utility>
11 12
12 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
13 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/sequenced_task_runner.h"
14 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/time/time.h" 18 #include "base/time/time.h"
16 #include "content/browser/child_process_security_policy_impl.h" 19 #include "content/browser/child_process_security_policy_impl.h"
17 #include "content/browser/fileapi/fileapi_message_filter.h" 20 #include "content/browser/fileapi/fileapi_message_filter.h"
18 #include "content/browser/indexed_db/cursor_impl.h" 21 #include "content/browser/indexed_db/cursor_impl.h"
19 #include "content/browser/indexed_db/database_impl.h" 22 #include "content/browser/indexed_db/database_impl.h"
20 #include "content/browser/indexed_db/indexed_db_connection.h" 23 #include "content/browser/indexed_db/indexed_db_connection.h"
21 #include "content/browser/indexed_db/indexed_db_context_impl.h" 24 #include "content/browser/indexed_db/indexed_db_context_impl.h"
22 #include "content/browser/indexed_db/indexed_db_cursor.h" 25 #include "content/browser/indexed_db/indexed_db_cursor.h"
23 #include "content/browser/indexed_db/indexed_db_database_error.h" 26 #include "content/browser/indexed_db/indexed_db_database_error.h"
24 #include "content/browser/indexed_db/indexed_db_return_value.h" 27 #include "content/browser/indexed_db/indexed_db_return_value.h"
25 #include "content/browser/indexed_db/indexed_db_tracing.h" 28 #include "content/browser/indexed_db/indexed_db_tracing.h"
26 #include "content/browser/indexed_db/indexed_db_transaction.h" 29 #include "content/browser/indexed_db/indexed_db_transaction.h"
27 #include "content/browser/indexed_db/indexed_db_value.h" 30 #include "content/browser/indexed_db/indexed_db_value.h"
28 #include "content/common/indexed_db/indexed_db_constants.h" 31 #include "content/common/indexed_db/indexed_db_constants.h"
29 #include "content/common/indexed_db/indexed_db_metadata.h" 32 #include "content/common/indexed_db/indexed_db_metadata.h"
33 #include "content/public/browser/browser_thread.h"
30 #include "mojo/public/cpp/bindings/strong_associated_binding.h" 34 #include "mojo/public/cpp/bindings/strong_associated_binding.h"
31 #include "storage/browser/blob/blob_storage_context.h" 35 #include "storage/browser/blob/blob_storage_context.h"
32 #include "storage/browser/blob/shareable_file_reference.h" 36 #include "storage/browser/blob/shareable_file_reference.h"
33 #include "storage/browser/quota/quota_manager.h" 37 #include "storage/browser/quota/quota_manager.h"
34 38
35 using indexed_db::mojom::CallbacksAssociatedPtrInfo; 39 using indexed_db::mojom::CallbacksAssociatedPtrInfo;
36 using std::swap; 40 using std::swap;
37 using storage::ShareableFileReference; 41 using storage::ShareableFileReference;
38 42
39 namespace content { 43 namespace content {
40 44
41 namespace { 45 namespace {
42 46
47 // If this is destructed with the connection still living inside it, we assume
48 // we have been killed due to IO thread shutdown, and we need to safely schedule
49 // the destruction of the connection on the IDB thread, as we should still be in
50 // a transaction's operation queue, where we cannot destroy the transaction.
51 struct SafeIOThreadConnectionWrapper {
52 SafeIOThreadConnectionWrapper(std::unique_ptr<IndexedDBConnection> connection)
53 : connection(std::move(connection)),
54 idb_runner(base::ThreadTaskRunnerHandle::Get()) {}
55 ~SafeIOThreadConnectionWrapper() {
56 if (connection) {
57 idb_runner->PostTask(
58 FROM_HERE, base::Bind(
59 [](std::unique_ptr<IndexedDBConnection> connection) {
60 connection->ForceClose();
61 },
62 base::Passed(&connection)));
63 }
64 }
65 SafeIOThreadConnectionWrapper(SafeIOThreadConnectionWrapper&& other) =
66 default;
67
68 std::unique_ptr<IndexedDBConnection> connection;
69 scoped_refptr<base::SequencedTaskRunner> idb_runner;
70
71 private:
72 DISALLOW_COPY_AND_ASSIGN(SafeIOThreadConnectionWrapper);
73 };
74
43 void ConvertBlobInfo( 75 void ConvertBlobInfo(
44 const std::vector<IndexedDBBlobInfo>& blob_info, 76 const std::vector<IndexedDBBlobInfo>& blob_info,
45 std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) { 77 std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) {
46 blob_or_file_info->reserve(blob_info.size()); 78 blob_or_file_info->reserve(blob_info.size());
47 for (const auto& iter : blob_info) { 79 for (const auto& iter : blob_info) {
48 if (!iter.mark_used_callback().is_null()) 80 if (!iter.mark_used_callback().is_null())
49 iter.mark_used_callback().Run(); 81 iter.mark_used_callback().Run();
50 82
51 auto info = ::indexed_db::mojom::BlobInfo::New(); 83 auto info = ::indexed_db::mojom::BlobInfo::New();
52 info->mime_type = iter.type(); 84 info->mime_type = iter.type();
(...skipping 21 matching lines...) Expand all
74 swap(mojo_value->value->bits, value->bits); 106 swap(mojo_value->value->bits, value->bits);
75 ConvertBlobInfo(value->blob_info, &mojo_value->value->blob_or_file_info); 107 ConvertBlobInfo(value->blob_info, &mojo_value->value->blob_or_file_info);
76 return mojo_value; 108 return mojo_value;
77 } 109 }
78 110
79 } // namespace 111 } // namespace
80 112
81 class IndexedDBCallbacks::IOThreadHelper { 113 class IndexedDBCallbacks::IOThreadHelper {
82 public: 114 public:
83 IOThreadHelper(CallbacksAssociatedPtrInfo callbacks_info, 115 IOThreadHelper(CallbacksAssociatedPtrInfo callbacks_info,
84 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host); 116 base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
117 url::Origin origin,
118 scoped_refptr<base::SequencedTaskRunner> idb_runner);
85 ~IOThreadHelper(); 119 ~IOThreadHelper();
86 120
87 void SendError(const IndexedDBDatabaseError& error); 121 void SendError(const IndexedDBDatabaseError& error);
88 void SendSuccessStringList(const std::vector<base::string16>& value); 122 void SendSuccessStringList(const std::vector<base::string16>& value);
89 void SendBlocked(int64_t existing_version); 123 void SendBlocked(int64_t existing_version);
90 void SendUpgradeNeeded(std::unique_ptr<DatabaseImpl> database, 124 void SendUpgradeNeeded(SafeIOThreadConnectionWrapper connection,
91 int64_t old_version, 125 int64_t old_version,
92 blink::WebIDBDataLoss data_loss, 126 blink::WebIDBDataLoss data_loss,
93 const std::string& data_loss_message, 127 const std::string& data_loss_message,
94 const content::IndexedDBDatabaseMetadata& metadata); 128 const content::IndexedDBDatabaseMetadata& metadata);
95 void SendSuccessDatabase(std::unique_ptr<DatabaseImpl> database, 129 void SendSuccessDatabase(SafeIOThreadConnectionWrapper connection,
96 const content::IndexedDBDatabaseMetadata& metadata); 130 const content::IndexedDBDatabaseMetadata& metadata);
97 void SendSuccessCursor(std::unique_ptr<CursorImpl> cursor, 131 void SendSuccessCursor(std::unique_ptr<IndexedDBCursor> cursor,
98 const IndexedDBKey& key, 132 const IndexedDBKey& key,
99 const IndexedDBKey& primary_key, 133 const IndexedDBKey& primary_key,
100 ::indexed_db::mojom::ValuePtr value, 134 ::indexed_db::mojom::ValuePtr value,
101 const std::vector<IndexedDBBlobInfo>& blob_info); 135 const std::vector<IndexedDBBlobInfo>& blob_info);
102 void SendSuccessValue(::indexed_db::mojom::ReturnValuePtr value, 136 void SendSuccessValue(::indexed_db::mojom::ReturnValuePtr value,
103 const std::vector<IndexedDBBlobInfo>& blob_info); 137 const std::vector<IndexedDBBlobInfo>& blob_info);
104 void SendSuccessCursorContinue( 138 void SendSuccessCursorContinue(
105 const IndexedDBKey& key, 139 const IndexedDBKey& key,
106 const IndexedDBKey& primary_key, 140 const IndexedDBKey& primary_key,
107 ::indexed_db::mojom::ValuePtr value, 141 ::indexed_db::mojom::ValuePtr value,
(...skipping 10 matching lines...) Expand all
118 void SendSuccessInteger(int64_t value); 152 void SendSuccessInteger(int64_t value);
119 void SendSuccess(); 153 void SendSuccess();
120 154
121 std::string CreateBlobData(const IndexedDBBlobInfo& blob_info); 155 std::string CreateBlobData(const IndexedDBBlobInfo& blob_info);
122 bool CreateAllBlobs( 156 bool CreateAllBlobs(
123 const std::vector<IndexedDBBlobInfo>& blob_info, 157 const std::vector<IndexedDBBlobInfo>& blob_info,
124 std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info); 158 std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info);
125 void OnConnectionError(); 159 void OnConnectionError();
126 160
127 private: 161 private:
128 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host_; 162 base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host_;
129 ::indexed_db::mojom::CallbacksAssociatedPtr callbacks_; 163 ::indexed_db::mojom::CallbacksAssociatedPtr callbacks_;
164 url::Origin origin_;
165 scoped_refptr<base::SequencedTaskRunner> idb_runner_;
130 166
131 DISALLOW_COPY_AND_ASSIGN(IOThreadHelper); 167 DISALLOW_COPY_AND_ASSIGN(IOThreadHelper);
132 }; 168 };
133 169
134 // static 170 // static
135 ::indexed_db::mojom::ValuePtr IndexedDBCallbacks::ConvertAndEraseValue( 171 ::indexed_db::mojom::ValuePtr IndexedDBCallbacks::ConvertAndEraseValue(
136 IndexedDBValue* value) { 172 IndexedDBValue* value) {
137 auto mojo_value = ::indexed_db::mojom::Value::New(); 173 auto mojo_value = ::indexed_db::mojom::Value::New();
138 if (!value->empty()) 174 if (!value->empty())
139 swap(mojo_value->bits, value->bits); 175 swap(mojo_value->bits, value->bits);
140 ConvertBlobInfo(value->blob_info, &mojo_value->blob_or_file_info); 176 ConvertBlobInfo(value->blob_info, &mojo_value->blob_or_file_info);
141 return mojo_value; 177 return mojo_value;
142 } 178 }
143 179
144 IndexedDBCallbacks::IndexedDBCallbacks( 180 IndexedDBCallbacks::IndexedDBCallbacks(
145 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, 181 base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
146 const url::Origin& origin, 182 const url::Origin& origin,
147 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) 183 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info,
148 : dispatcher_host_(std::move(dispatcher_host)), 184 scoped_refptr<base::SequencedTaskRunner> idb_runner)
149 origin_(origin), 185 : data_loss_(blink::kWebIDBDataLossNone),
150 data_loss_(blink::kWebIDBDataLossNone), 186 io_helper_(new IOThreadHelper(std::move(callbacks_info),
151 sent_blocked_(false), 187 std::move(dispatcher_host),
152 io_helper_( 188 origin,
153 new IOThreadHelper(std::move(callbacks_info), dispatcher_host_)) { 189 std::move(idb_runner))) {
154 DCHECK_CURRENTLY_ON(BrowserThread::IO); 190 DCHECK_CURRENTLY_ON(BrowserThread::IO);
155 thread_checker_.DetachFromThread(); 191 thread_checker_.DetachFromThread();
156 } 192 }
157 193
158 IndexedDBCallbacks::~IndexedDBCallbacks() { 194 IndexedDBCallbacks::~IndexedDBCallbacks() {
159 DCHECK(thread_checker_.CalledOnValidThread()); 195 DCHECK(thread_checker_.CalledOnValidThread());
160 } 196 }
161 197
162 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) { 198 void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) {
163 DCHECK(thread_checker_.CalledOnValidThread()); 199 DCHECK(thread_checker_.CalledOnValidThread());
164 DCHECK(dispatcher_host_); 200 DCHECK(!closed_);
165 201
166 BrowserThread::PostTask( 202 BrowserThread::PostTask(
167 BrowserThread::IO, FROM_HERE, 203 BrowserThread::IO, FROM_HERE,
168 base::Bind(&IOThreadHelper::SendError, base::Unretained(io_helper_.get()), 204 base::Bind(&IOThreadHelper::SendError, base::Unretained(io_helper_.get()),
169 error)); 205 error));
170 dispatcher_host_ = nullptr; 206 closed_ = true;
171 207
172 if (!connection_open_start_time_.is_null()) { 208 if (!connection_open_start_time_.is_null()) {
173 UMA_HISTOGRAM_MEDIUM_TIMES( 209 UMA_HISTOGRAM_MEDIUM_TIMES(
174 "WebCore.IndexedDB.OpenTime.Error", 210 "WebCore.IndexedDB.OpenTime.Error",
175 base::TimeTicks::Now() - connection_open_start_time_); 211 base::TimeTicks::Now() - connection_open_start_time_);
176 connection_open_start_time_ = base::TimeTicks(); 212 connection_open_start_time_ = base::TimeTicks();
177 } 213 }
178 } 214 }
179 215
180 void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) { 216 void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
181 DCHECK(thread_checker_.CalledOnValidThread()); 217 DCHECK(thread_checker_.CalledOnValidThread());
182 DCHECK(dispatcher_host_); 218 DCHECK(!closed_);
183 DCHECK(io_helper_); 219 DCHECK(io_helper_);
184 220
185 BrowserThread::PostTask( 221 BrowserThread::PostTask(
186 BrowserThread::IO, FROM_HERE, 222 BrowserThread::IO, FROM_HERE,
187 base::Bind(&IOThreadHelper::SendSuccessStringList, 223 base::Bind(&IOThreadHelper::SendSuccessStringList,
188 base::Unretained(io_helper_.get()), value)); 224 base::Unretained(io_helper_.get()), value));
189 dispatcher_host_ = nullptr; 225 closed_ = true;
190 } 226 }
191 227
192 void IndexedDBCallbacks::OnBlocked(int64_t existing_version) { 228 void IndexedDBCallbacks::OnBlocked(int64_t existing_version) {
193 DCHECK(thread_checker_.CalledOnValidThread()); 229 DCHECK(thread_checker_.CalledOnValidThread());
194 DCHECK(dispatcher_host_); 230 DCHECK(!closed_);
195 DCHECK(io_helper_); 231 DCHECK(io_helper_);
196 232
197 if (sent_blocked_) 233 if (sent_blocked_)
198 return; 234 return;
199 235
200 sent_blocked_ = true; 236 sent_blocked_ = true;
201 237
202 BrowserThread::PostTask( 238 BrowserThread::PostTask(
203 BrowserThread::IO, FROM_HERE, 239 BrowserThread::IO, FROM_HERE,
204 base::Bind(&IOThreadHelper::SendBlocked, 240 base::Bind(&IOThreadHelper::SendBlocked,
205 base::Unretained(io_helper_.get()), existing_version)); 241 base::Unretained(io_helper_.get()), existing_version));
206 242
207 if (!connection_open_start_time_.is_null()) { 243 if (!connection_open_start_time_.is_null()) {
208 UMA_HISTOGRAM_MEDIUM_TIMES( 244 UMA_HISTOGRAM_MEDIUM_TIMES(
209 "WebCore.IndexedDB.OpenTime.Blocked", 245 "WebCore.IndexedDB.OpenTime.Blocked",
210 base::TimeTicks::Now() - connection_open_start_time_); 246 base::TimeTicks::Now() - connection_open_start_time_);
211 connection_open_start_time_ = base::TimeTicks(); 247 connection_open_start_time_ = base::TimeTicks();
212 } 248 }
213 } 249 }
214 250
215 void IndexedDBCallbacks::OnUpgradeNeeded( 251 void IndexedDBCallbacks::OnUpgradeNeeded(
216 int64_t old_version, 252 int64_t old_version,
217 std::unique_ptr<IndexedDBConnection> connection, 253 std::unique_ptr<IndexedDBConnection> connection,
218 const IndexedDBDatabaseMetadata& metadata, 254 const IndexedDBDatabaseMetadata& metadata,
219 const IndexedDBDataLossInfo& data_loss_info) { 255 const IndexedDBDataLossInfo& data_loss_info) {
220 DCHECK(thread_checker_.CalledOnValidThread()); 256 DCHECK(thread_checker_.CalledOnValidThread());
221 DCHECK(dispatcher_host_); 257 DCHECK(!closed_);
222 DCHECK(io_helper_); 258 DCHECK(io_helper_);
223 259
224 DCHECK(!database_sent_); 260 DCHECK(!database_created_);
jsbell 2017/04/11 16:58:04 This should really refer to 'connection' not 'data
dmurph 2017/04/11 19:32:49 Done.
225 261
226 data_loss_ = data_loss_info.status; 262 data_loss_ = data_loss_info.status;
227 database_sent_ = true; 263 database_created_ = true;
228 auto database = base::MakeUnique<DatabaseImpl>(std::move(connection), origin_,
229 dispatcher_host_);
230 264
265 SafeIOThreadConnectionWrapper wrapper(std::move(connection));
231 BrowserThread::PostTask( 266 BrowserThread::PostTask(
232 BrowserThread::IO, FROM_HERE, 267 BrowserThread::IO, FROM_HERE,
233 base::Bind(&IOThreadHelper::SendUpgradeNeeded, 268 base::Bind(&IOThreadHelper::SendUpgradeNeeded,
234 base::Unretained(io_helper_.get()), base::Passed(&database), 269 base::Unretained(io_helper_.get()), base::Passed(&wrapper),
235 old_version, data_loss_info.status, data_loss_info.message, 270 old_version, data_loss_info.status, data_loss_info.message,
236 metadata)); 271 metadata));
237 272
238 if (!connection_open_start_time_.is_null()) { 273 if (!connection_open_start_time_.is_null()) {
239 UMA_HISTOGRAM_MEDIUM_TIMES( 274 UMA_HISTOGRAM_MEDIUM_TIMES(
240 "WebCore.IndexedDB.OpenTime.UpgradeNeeded", 275 "WebCore.IndexedDB.OpenTime.UpgradeNeeded",
241 base::TimeTicks::Now() - connection_open_start_time_); 276 base::TimeTicks::Now() - connection_open_start_time_);
242 connection_open_start_time_ = base::TimeTicks(); 277 connection_open_start_time_ = base::TimeTicks();
243 } 278 }
244 } 279 }
245 280
246 void IndexedDBCallbacks::OnSuccess( 281 void IndexedDBCallbacks::OnSuccess(
247 std::unique_ptr<IndexedDBConnection> connection, 282 std::unique_ptr<IndexedDBConnection> connection,
248 const IndexedDBDatabaseMetadata& metadata) { 283 const IndexedDBDatabaseMetadata& metadata) {
249 DCHECK(thread_checker_.CalledOnValidThread()); 284 DCHECK(thread_checker_.CalledOnValidThread());
250 DCHECK(dispatcher_host_); 285 DCHECK(!closed_);
251 DCHECK(io_helper_); 286 DCHECK(io_helper_);
252 287
253 DCHECK_EQ(database_sent_, !connection); 288 DCHECK_EQ(database_created_, !connection);
254 289
255 scoped_refptr<IndexedDBCallbacks> self(this); 290 scoped_refptr<IndexedDBCallbacks> self(this);
256 291
257 // Only send a new Database if the connection was not previously sent in 292 // Only create a new connection if the database was not previously sent in
jsbell 2017/04/11 16:58:03 s/database/one/
dmurph 2017/04/11 19:32:49 Done.
258 // OnUpgradeNeeded. 293 // OnUpgradeNeeded.
259 std::unique_ptr<DatabaseImpl> database; 294 std::unique_ptr<IndexedDBConnection> database_connection;
260 if (!database_sent_) { 295 if (!database_created_)
261 database.reset( 296 database_connection = std::move(connection);
262 new DatabaseImpl(std::move(connection), origin_, dispatcher_host_));
263 }
264 297
298 SafeIOThreadConnectionWrapper wrapper(std::move(database_connection));
265 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 299 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
266 base::Bind(&IOThreadHelper::SendSuccessDatabase, 300 base::Bind(&IOThreadHelper::SendSuccessDatabase,
267 base::Unretained(io_helper_.get()), 301 base::Unretained(io_helper_.get()),
268 base::Passed(&database), metadata)); 302 base::Passed(&wrapper), metadata));
269 dispatcher_host_ = nullptr; 303 closed_ = true;
jsbell 2017/04/11 16:58:04 Seeing this usage, maybe rename 'complete_' or 'do
dmurph 2017/04/11 19:32:49 Done.
270 304
271 if (!connection_open_start_time_.is_null()) { 305 if (!connection_open_start_time_.is_null()) {
272 UMA_HISTOGRAM_MEDIUM_TIMES( 306 UMA_HISTOGRAM_MEDIUM_TIMES(
273 "WebCore.IndexedDB.OpenTime.Success", 307 "WebCore.IndexedDB.OpenTime.Success",
274 base::TimeTicks::Now() - connection_open_start_time_); 308 base::TimeTicks::Now() - connection_open_start_time_);
275 connection_open_start_time_ = base::TimeTicks(); 309 connection_open_start_time_ = base::TimeTicks();
276 } 310 }
277 } 311 }
278 312
279 void IndexedDBCallbacks::OnSuccess(std::unique_ptr<IndexedDBCursor> cursor, 313 void IndexedDBCallbacks::OnSuccess(std::unique_ptr<IndexedDBCursor> cursor,
280 const IndexedDBKey& key, 314 const IndexedDBKey& key,
281 const IndexedDBKey& primary_key, 315 const IndexedDBKey& primary_key,
282 IndexedDBValue* value) { 316 IndexedDBValue* value) {
283 DCHECK(thread_checker_.CalledOnValidThread()); 317 DCHECK(thread_checker_.CalledOnValidThread());
284 DCHECK(dispatcher_host_); 318 DCHECK(!closed_);
285 DCHECK(io_helper_); 319 DCHECK(io_helper_);
286 320
287 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); 321 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
288 322
289 auto cursor_impl = base::MakeUnique<CursorImpl>(std::move(cursor), origin_,
290 dispatcher_host_);
291
292 ::indexed_db::mojom::ValuePtr mojo_value; 323 ::indexed_db::mojom::ValuePtr mojo_value;
293 std::vector<IndexedDBBlobInfo> blob_info; 324 std::vector<IndexedDBBlobInfo> blob_info;
294 if (value) { 325 if (value) {
295 mojo_value = ConvertAndEraseValue(value); 326 mojo_value = ConvertAndEraseValue(value);
296 blob_info.swap(value->blob_info); 327 blob_info.swap(value->blob_info);
297 } 328 }
298 329
299 BrowserThread::PostTask( 330 BrowserThread::PostTask(
300 BrowserThread::IO, FROM_HERE, 331 BrowserThread::IO, FROM_HERE,
301 base::Bind(&IOThreadHelper::SendSuccessCursor, 332 base::Bind(&IOThreadHelper::SendSuccessCursor,
302 base::Unretained(io_helper_.get()), base::Passed(&cursor_impl), 333 base::Unretained(io_helper_.get()), base::Passed(&cursor), key,
303 key, primary_key, base::Passed(&mojo_value), 334 primary_key, base::Passed(&mojo_value),
304 base::Passed(&blob_info))); 335 base::Passed(&blob_info)));
305 dispatcher_host_ = nullptr; 336 closed_ = true;
306 } 337 }
307 338
308 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, 339 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
309 const IndexedDBKey& primary_key, 340 const IndexedDBKey& primary_key,
310 IndexedDBValue* value) { 341 IndexedDBValue* value) {
311 DCHECK(thread_checker_.CalledOnValidThread()); 342 DCHECK(thread_checker_.CalledOnValidThread());
312 DCHECK(dispatcher_host_); 343 DCHECK(!closed_);
313 DCHECK(io_helper_); 344 DCHECK(io_helper_);
314 345
315 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); 346 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
316 347
317 ::indexed_db::mojom::ValuePtr mojo_value; 348 ::indexed_db::mojom::ValuePtr mojo_value;
318 std::vector<IndexedDBBlobInfo> blob_info; 349 std::vector<IndexedDBBlobInfo> blob_info;
319 if (value) { 350 if (value) {
320 mojo_value = ConvertAndEraseValue(value); 351 mojo_value = ConvertAndEraseValue(value);
321 blob_info.swap(value->blob_info); 352 blob_info.swap(value->blob_info);
322 } 353 }
323 354
324 BrowserThread::PostTask( 355 BrowserThread::PostTask(
325 BrowserThread::IO, FROM_HERE, 356 BrowserThread::IO, FROM_HERE,
326 base::Bind(&IOThreadHelper::SendSuccessCursorContinue, 357 base::Bind(&IOThreadHelper::SendSuccessCursorContinue,
327 base::Unretained(io_helper_.get()), key, primary_key, 358 base::Unretained(io_helper_.get()), key, primary_key,
328 base::Passed(&mojo_value), base::Passed(&blob_info))); 359 base::Passed(&mojo_value), base::Passed(&blob_info)));
329 dispatcher_host_ = nullptr; 360 closed_ = true;
330 } 361 }
331 362
332 void IndexedDBCallbacks::OnSuccessWithPrefetch( 363 void IndexedDBCallbacks::OnSuccessWithPrefetch(
333 const std::vector<IndexedDBKey>& keys, 364 const std::vector<IndexedDBKey>& keys,
334 const std::vector<IndexedDBKey>& primary_keys, 365 const std::vector<IndexedDBKey>& primary_keys,
335 std::vector<IndexedDBValue>* values) { 366 std::vector<IndexedDBValue>* values) {
336 DCHECK(thread_checker_.CalledOnValidThread()); 367 DCHECK(thread_checker_.CalledOnValidThread());
337 DCHECK(dispatcher_host_); 368 DCHECK(!closed_);
338 DCHECK(io_helper_); 369 DCHECK(io_helper_);
339 DCHECK_EQ(keys.size(), primary_keys.size()); 370 DCHECK_EQ(keys.size(), primary_keys.size());
340 DCHECK_EQ(keys.size(), values->size()); 371 DCHECK_EQ(keys.size(), values->size());
341 372
342 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); 373 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
343 374
344 std::vector<::indexed_db::mojom::ValuePtr> mojo_values; 375 std::vector<::indexed_db::mojom::ValuePtr> mojo_values;
345 mojo_values.reserve(values->size()); 376 mojo_values.reserve(values->size());
346 for (size_t i = 0; i < values->size(); ++i) 377 for (size_t i = 0; i < values->size(); ++i)
347 mojo_values.push_back(ConvertAndEraseValue(&(*values)[i])); 378 mojo_values.push_back(ConvertAndEraseValue(&(*values)[i]));
348 379
349 BrowserThread::PostTask( 380 BrowserThread::PostTask(
350 BrowserThread::IO, FROM_HERE, 381 BrowserThread::IO, FROM_HERE,
351 base::Bind(&IOThreadHelper::SendSuccessCursorPrefetch, 382 base::Bind(&IOThreadHelper::SendSuccessCursorPrefetch,
352 base::Unretained(io_helper_.get()), keys, primary_keys, 383 base::Unretained(io_helper_.get()), keys, primary_keys,
353 base::Passed(&mojo_values), *values)); 384 base::Passed(&mojo_values), *values));
354 dispatcher_host_ = nullptr; 385 closed_ = true;
355 } 386 }
356 387
357 void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) { 388 void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) {
358 DCHECK(thread_checker_.CalledOnValidThread()); 389 DCHECK(thread_checker_.CalledOnValidThread());
359 DCHECK(dispatcher_host_); 390 DCHECK(!closed_);
360 391
361 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); 392 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
362 393
363 ::indexed_db::mojom::ReturnValuePtr mojo_value; 394 ::indexed_db::mojom::ReturnValuePtr mojo_value;
364 std::vector<IndexedDBBlobInfo> blob_info; 395 std::vector<IndexedDBBlobInfo> blob_info;
365 if (value) { 396 if (value) {
366 mojo_value = ConvertReturnValue(value); 397 mojo_value = ConvertReturnValue(value);
367 blob_info = value->blob_info; 398 blob_info = value->blob_info;
368 } 399 }
369 400
370 BrowserThread::PostTask( 401 BrowserThread::PostTask(
371 BrowserThread::IO, FROM_HERE, 402 BrowserThread::IO, FROM_HERE,
372 base::Bind(&IOThreadHelper::SendSuccessValue, 403 base::Bind(&IOThreadHelper::SendSuccessValue,
373 base::Unretained(io_helper_.get()), base::Passed(&mojo_value), 404 base::Unretained(io_helper_.get()), base::Passed(&mojo_value),
374 base::Passed(&blob_info))); 405 base::Passed(&blob_info)));
375 dispatcher_host_ = nullptr; 406 closed_ = true;
376 } 407 }
377 408
378 void IndexedDBCallbacks::OnSuccessArray( 409 void IndexedDBCallbacks::OnSuccessArray(
379 std::vector<IndexedDBReturnValue>* values) { 410 std::vector<IndexedDBReturnValue>* values) {
380 DCHECK(thread_checker_.CalledOnValidThread()); 411 DCHECK(thread_checker_.CalledOnValidThread());
381 DCHECK(dispatcher_host_); 412 DCHECK(!closed_);
382 DCHECK(io_helper_); 413 DCHECK(io_helper_);
383 414
384 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); 415 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
385 416
386 std::vector<::indexed_db::mojom::ReturnValuePtr> mojo_values; 417 std::vector<::indexed_db::mojom::ReturnValuePtr> mojo_values;
387 mojo_values.reserve(values->size()); 418 mojo_values.reserve(values->size());
388 for (size_t i = 0; i < values->size(); ++i) 419 for (size_t i = 0; i < values->size(); ++i)
389 mojo_values.push_back(ConvertReturnValue(&(*values)[i])); 420 mojo_values.push_back(ConvertReturnValue(&(*values)[i]));
390 421
391 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 422 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
392 base::Bind(&IOThreadHelper::SendSuccessArray, 423 base::Bind(&IOThreadHelper::SendSuccessArray,
393 base::Unretained(io_helper_.get()), 424 base::Unretained(io_helper_.get()),
394 base::Passed(&mojo_values), *values)); 425 base::Passed(&mojo_values), *values));
395 dispatcher_host_ = nullptr; 426 closed_ = true;
396 } 427 }
397 428
398 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { 429 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
399 DCHECK(thread_checker_.CalledOnValidThread()); 430 DCHECK(thread_checker_.CalledOnValidThread());
400 DCHECK(dispatcher_host_); 431 DCHECK(!closed_);
401 DCHECK(io_helper_); 432 DCHECK(io_helper_);
402 433
403 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); 434 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
404 435
405 BrowserThread::PostTask( 436 BrowserThread::PostTask(
406 BrowserThread::IO, FROM_HERE, 437 BrowserThread::IO, FROM_HERE,
407 base::Bind(&IOThreadHelper::SendSuccessKey, 438 base::Bind(&IOThreadHelper::SendSuccessKey,
408 base::Unretained(io_helper_.get()), value)); 439 base::Unretained(io_helper_.get()), value));
409 dispatcher_host_ = nullptr; 440 closed_ = true;
410 } 441 }
411 442
412 void IndexedDBCallbacks::OnSuccess(int64_t value) { 443 void IndexedDBCallbacks::OnSuccess(int64_t value) {
413 DCHECK(thread_checker_.CalledOnValidThread()); 444 DCHECK(thread_checker_.CalledOnValidThread());
414 DCHECK(dispatcher_host_); 445 DCHECK(!closed_);
415 446
416 BrowserThread::PostTask( 447 BrowserThread::PostTask(
417 BrowserThread::IO, FROM_HERE, 448 BrowserThread::IO, FROM_HERE,
418 base::Bind(&IOThreadHelper::SendSuccessInteger, 449 base::Bind(&IOThreadHelper::SendSuccessInteger,
419 base::Unretained(io_helper_.get()), value)); 450 base::Unretained(io_helper_.get()), value));
420 dispatcher_host_ = nullptr; 451 closed_ = true;
421 } 452 }
422 453
423 void IndexedDBCallbacks::OnSuccess() { 454 void IndexedDBCallbacks::OnSuccess() {
424 DCHECK(thread_checker_.CalledOnValidThread()); 455 DCHECK(thread_checker_.CalledOnValidThread());
425 DCHECK(dispatcher_host_); 456 DCHECK(!closed_);
426 DCHECK(io_helper_); 457 DCHECK(io_helper_);
427 458
428 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); 459 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
429 460
430 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 461 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
431 base::Bind(&IOThreadHelper::SendSuccess, 462 base::Bind(&IOThreadHelper::SendSuccess,
432 base::Unretained(io_helper_.get()))); 463 base::Unretained(io_helper_.get())));
433 dispatcher_host_ = nullptr; 464 closed_ = true;
434 } 465 }
435 466
436 void IndexedDBCallbacks::SetConnectionOpenStartTime( 467 void IndexedDBCallbacks::SetConnectionOpenStartTime(
437 const base::TimeTicks& start_time) { 468 const base::TimeTicks& start_time) {
438 connection_open_start_time_ = start_time; 469 connection_open_start_time_ = start_time;
439 } 470 }
440 471
441 IndexedDBCallbacks::IOThreadHelper::IOThreadHelper( 472 IndexedDBCallbacks::IOThreadHelper::IOThreadHelper(
442 CallbacksAssociatedPtrInfo callbacks_info, 473 CallbacksAssociatedPtrInfo callbacks_info,
443 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) 474 base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
444 : dispatcher_host_(std::move(dispatcher_host)) { 475 url::Origin origin,
476 scoped_refptr<base::SequencedTaskRunner> idb_runner)
477 : dispatcher_host_(std::move(dispatcher_host)),
478 origin_(origin),
479 idb_runner_(idb_runner) {
445 DCHECK_CURRENTLY_ON(BrowserThread::IO); 480 DCHECK_CURRENTLY_ON(BrowserThread::IO);
446 if (callbacks_info.is_valid()) { 481 if (callbacks_info.is_valid()) {
447 callbacks_.Bind(std::move(callbacks_info)); 482 callbacks_.Bind(std::move(callbacks_info));
448 callbacks_.set_connection_error_handler( 483 callbacks_.set_connection_error_handler(
449 base::Bind(&IOThreadHelper::OnConnectionError, base::Unretained(this))); 484 base::Bind(&IOThreadHelper::OnConnectionError, base::Unretained(this)));
450 } 485 }
451 } 486 }
452 487
453 IndexedDBCallbacks::IOThreadHelper::~IOThreadHelper() {} 488 IndexedDBCallbacks::IOThreadHelper::~IOThreadHelper() {}
454 489
455 void IndexedDBCallbacks::IOThreadHelper::SendError( 490 void IndexedDBCallbacks::IOThreadHelper::SendError(
456 const IndexedDBDatabaseError& error) { 491 const IndexedDBDatabaseError& error) {
457 if (callbacks_) 492 if (!callbacks_)
458 callbacks_->Error(error.code(), error.message()); 493 return;
494 if (!dispatcher_host_) {
495 OnConnectionError();
496 return;
497 }
498 callbacks_->Error(error.code(), error.message());
459 } 499 }
460 500
461 void IndexedDBCallbacks::IOThreadHelper::SendSuccessStringList( 501 void IndexedDBCallbacks::IOThreadHelper::SendSuccessStringList(
462 const std::vector<base::string16>& value) { 502 const std::vector<base::string16>& value) {
463 if (callbacks_) 503 if (!callbacks_)
464 callbacks_->SuccessStringList(value); 504 return;
505 if (!dispatcher_host_) {
506 OnConnectionError();
507 return;
508 }
509 callbacks_->SuccessStringList(value);
465 } 510 }
466 511
467 void IndexedDBCallbacks::IOThreadHelper::SendBlocked(int64_t existing_version) { 512 void IndexedDBCallbacks::IOThreadHelper::SendBlocked(int64_t existing_version) {
513 if (!dispatcher_host_) {
514 OnConnectionError();
515 return;
516 }
468 if (callbacks_) 517 if (callbacks_)
469 callbacks_->Blocked(existing_version); 518 callbacks_->Blocked(existing_version);
470 } 519 }
471 520
472 void IndexedDBCallbacks::IOThreadHelper::SendUpgradeNeeded( 521 void IndexedDBCallbacks::IOThreadHelper::SendUpgradeNeeded(
473 std::unique_ptr<DatabaseImpl> database, 522 SafeIOThreadConnectionWrapper connection_wrapper,
474 int64_t old_version, 523 int64_t old_version,
475 blink::WebIDBDataLoss data_loss, 524 blink::WebIDBDataLoss data_loss,
476 const std::string& data_loss_message, 525 const std::string& data_loss_message,
477 const content::IndexedDBDatabaseMetadata& metadata) { 526 const content::IndexedDBDatabaseMetadata& metadata) {
478 if (!callbacks_) 527 if (!callbacks_)
479 return; 528 return;
529 if (!dispatcher_host_) {
530 OnConnectionError();
531 return;
532 }
533
534 auto database = base::MakeUnique<DatabaseImpl>(
535 std::move(connection_wrapper.connection), origin_, dispatcher_host_.get(),
536 idb_runner_);
480 537
481 ::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info; 538 ::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info;
482 auto request = mojo::MakeRequest(&ptr_info); 539 auto request = mojo::MakeRequest(&ptr_info);
483 mojo::MakeStrongAssociatedBinding(std::move(database), std::move(request)); 540
541 dispatcher_host_->AddDatabaseBinding(std::move(database), std::move(request));
484 callbacks_->UpgradeNeeded(std::move(ptr_info), old_version, data_loss, 542 callbacks_->UpgradeNeeded(std::move(ptr_info), old_version, data_loss,
485 data_loss_message, metadata); 543 data_loss_message, metadata);
486 } 544 }
487 545
488 void IndexedDBCallbacks::IOThreadHelper::SendSuccessDatabase( 546 void IndexedDBCallbacks::IOThreadHelper::SendSuccessDatabase(
489 std::unique_ptr<DatabaseImpl> database, 547 SafeIOThreadConnectionWrapper connection_wrapper,
490 const content::IndexedDBDatabaseMetadata& metadata) { 548 const content::IndexedDBDatabaseMetadata& metadata) {
491 if (!callbacks_) 549 if (!callbacks_)
492 return; 550 return;
551 if (!dispatcher_host_) {
552 OnConnectionError();
553 return;
554 }
555 ::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info;
556 if (connection_wrapper.connection) {
557 auto database = base::MakeUnique<DatabaseImpl>(
558 std::move(connection_wrapper.connection), origin_,
559 dispatcher_host_.get(), idb_runner_);
493 560
494 ::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info;
495 if (database) {
496 auto request = mojo::MakeRequest(&ptr_info); 561 auto request = mojo::MakeRequest(&ptr_info);
497 mojo::MakeStrongAssociatedBinding(std::move(database), std::move(request)); 562 dispatcher_host_->AddDatabaseBinding(std::move(database),
563 std::move(request));
498 } 564 }
499 callbacks_->SuccessDatabase(std::move(ptr_info), metadata); 565 callbacks_->SuccessDatabase(std::move(ptr_info), metadata);
500 } 566 }
501 567
502 void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor( 568 void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor(
503 std::unique_ptr<CursorImpl> cursor, 569 std::unique_ptr<IndexedDBCursor> cursor,
504 const IndexedDBKey& key, 570 const IndexedDBKey& key,
505 const IndexedDBKey& primary_key, 571 const IndexedDBKey& primary_key,
506 ::indexed_db::mojom::ValuePtr value, 572 ::indexed_db::mojom::ValuePtr value,
507 const std::vector<IndexedDBBlobInfo>& blob_info) { 573 const std::vector<IndexedDBBlobInfo>& blob_info) {
508 if (!callbacks_) 574 if (!callbacks_)
509 return; 575 return;
576 if (!dispatcher_host_) {
577 OnConnectionError();
578 return;
579 }
580 auto cursor_impl = base::MakeUnique<CursorImpl>(
581 std::move(cursor), origin_, dispatcher_host_.get(), idb_runner_);
510 582
511 if (value && !CreateAllBlobs(blob_info, &value->blob_or_file_info)) 583 if (value && !CreateAllBlobs(blob_info, &value->blob_or_file_info))
512 return; 584 return;
513 585
514 ::indexed_db::mojom::CursorAssociatedPtrInfo ptr_info; 586 ::indexed_db::mojom::CursorAssociatedPtrInfo ptr_info;
515 auto request = mojo::MakeRequest(&ptr_info); 587 auto request = mojo::MakeRequest(&ptr_info);
516 mojo::MakeStrongAssociatedBinding(std::move(cursor), std::move(request)); 588 dispatcher_host_->AddCursorBinding(std::move(cursor_impl),
589 std::move(request));
517 callbacks_->SuccessCursor(std::move(ptr_info), key, primary_key, 590 callbacks_->SuccessCursor(std::move(ptr_info), key, primary_key,
518 std::move(value)); 591 std::move(value));
519 } 592 }
520 593
521 void IndexedDBCallbacks::IOThreadHelper::SendSuccessValue( 594 void IndexedDBCallbacks::IOThreadHelper::SendSuccessValue(
522 ::indexed_db::mojom::ReturnValuePtr value, 595 ::indexed_db::mojom::ReturnValuePtr value,
523 const std::vector<IndexedDBBlobInfo>& blob_info) { 596 const std::vector<IndexedDBBlobInfo>& blob_info) {
524 if (!callbacks_) 597 if (!callbacks_)
525 return; 598 return;
599 if (!dispatcher_host_) {
600 OnConnectionError();
601 return;
602 }
526 603
527 if (!value || CreateAllBlobs(blob_info, &value->value->blob_or_file_info)) 604 if (!value || CreateAllBlobs(blob_info, &value->value->blob_or_file_info))
528 callbacks_->SuccessValue(std::move(value)); 605 callbacks_->SuccessValue(std::move(value));
529 } 606 }
530 607
531 void IndexedDBCallbacks::IOThreadHelper::SendSuccessArray( 608 void IndexedDBCallbacks::IOThreadHelper::SendSuccessArray(
532 std::vector<::indexed_db::mojom::ReturnValuePtr> mojo_values, 609 std::vector<::indexed_db::mojom::ReturnValuePtr> mojo_values,
533 const std::vector<IndexedDBReturnValue>& values) { 610 const std::vector<IndexedDBReturnValue>& values) {
534 DCHECK_EQ(mojo_values.size(), values.size()); 611 DCHECK_EQ(mojo_values.size(), values.size());
535 612
536 if (!callbacks_) 613 if (!callbacks_)
537 return; 614 return;
615 if (!dispatcher_host_) {
616 OnConnectionError();
617 return;
618 }
538 619
539 for (size_t i = 0; i < mojo_values.size(); ++i) { 620 for (size_t i = 0; i < mojo_values.size(); ++i) {
540 if (!CreateAllBlobs(values[i].blob_info, 621 if (!CreateAllBlobs(values[i].blob_info,
541 &mojo_values[i]->value->blob_or_file_info)) 622 &mojo_values[i]->value->blob_or_file_info))
542 return; 623 return;
543 } 624 }
544 callbacks_->SuccessArray(std::move(mojo_values)); 625 callbacks_->SuccessArray(std::move(mojo_values));
545 } 626 }
546 627
547 void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorContinue( 628 void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorContinue(
548 const IndexedDBKey& key, 629 const IndexedDBKey& key,
549 const IndexedDBKey& primary_key, 630 const IndexedDBKey& primary_key,
550 ::indexed_db::mojom::ValuePtr value, 631 ::indexed_db::mojom::ValuePtr value,
551 const std::vector<IndexedDBBlobInfo>& blob_info) { 632 const std::vector<IndexedDBBlobInfo>& blob_info) {
552 if (!callbacks_) 633 if (!callbacks_)
553 return; 634 return;
635 if (!dispatcher_host_) {
636 OnConnectionError();
637 return;
638 }
554 639
555 if (!value || CreateAllBlobs(blob_info, &value->blob_or_file_info)) 640 if (!value || CreateAllBlobs(blob_info, &value->blob_or_file_info))
556 callbacks_->SuccessCursorContinue(key, primary_key, std::move(value)); 641 callbacks_->SuccessCursorContinue(key, primary_key, std::move(value));
557 } 642 }
558 643
559 void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorPrefetch( 644 void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorPrefetch(
560 const std::vector<IndexedDBKey>& keys, 645 const std::vector<IndexedDBKey>& keys,
561 const std::vector<IndexedDBKey>& primary_keys, 646 const std::vector<IndexedDBKey>& primary_keys,
562 std::vector<::indexed_db::mojom::ValuePtr> mojo_values, 647 std::vector<::indexed_db::mojom::ValuePtr> mojo_values,
563 const std::vector<IndexedDBValue>& values) { 648 const std::vector<IndexedDBValue>& values) {
564 DCHECK_EQ(mojo_values.size(), values.size()); 649 DCHECK_EQ(mojo_values.size(), values.size());
565 650
566 if (!callbacks_) 651 if (!callbacks_)
567 return; 652 return;
653 if (!dispatcher_host_) {
654 OnConnectionError();
655 return;
656 }
568 657
569 for (size_t i = 0; i < mojo_values.size(); ++i) { 658 for (size_t i = 0; i < mojo_values.size(); ++i) {
570 if (!CreateAllBlobs(values[i].blob_info, 659 if (!CreateAllBlobs(values[i].blob_info,
571 &mojo_values[i]->blob_or_file_info)) { 660 &mojo_values[i]->blob_or_file_info)) {
572 return; 661 return;
573 } 662 }
574 } 663 }
575 664
576 callbacks_->SuccessCursorPrefetch(keys, primary_keys, std::move(mojo_values)); 665 callbacks_->SuccessCursorPrefetch(keys, primary_keys, std::move(mojo_values));
577 } 666 }
578 667
579 void IndexedDBCallbacks::IOThreadHelper::SendSuccessKey( 668 void IndexedDBCallbacks::IOThreadHelper::SendSuccessKey(
580 const IndexedDBKey& value) { 669 const IndexedDBKey& value) {
581 if (callbacks_) 670 if (!callbacks_)
582 callbacks_->SuccessKey(value); 671 return;
672 if (!dispatcher_host_) {
673 OnConnectionError();
674 return;
675 }
676 callbacks_->SuccessKey(value);
583 } 677 }
584 678
585 void IndexedDBCallbacks::IOThreadHelper::SendSuccessInteger(int64_t value) { 679 void IndexedDBCallbacks::IOThreadHelper::SendSuccessInteger(int64_t value) {
586 if (callbacks_) 680 if (!callbacks_)
587 callbacks_->SuccessInteger(value); 681 return;
682 if (!dispatcher_host_) {
683 OnConnectionError();
684 return;
685 }
686 callbacks_->SuccessInteger(value);
588 } 687 }
589 688
590 void IndexedDBCallbacks::IOThreadHelper::SendSuccess() { 689 void IndexedDBCallbacks::IOThreadHelper::SendSuccess() {
591 if (callbacks_) 690 if (!callbacks_)
592 callbacks_->Success(); 691 return;
692 if (!dispatcher_host_) {
693 OnConnectionError();
694 return;
695 }
696 callbacks_->Success();
593 } 697 }
594 698
595 std::string IndexedDBCallbacks::IOThreadHelper::CreateBlobData( 699 std::string IndexedDBCallbacks::IOThreadHelper::CreateBlobData(
596 const IndexedDBBlobInfo& blob_info) { 700 const IndexedDBBlobInfo& blob_info) {
597 if (!blob_info.uuid().empty()) { 701 if (!blob_info.uuid().empty()) {
598 // We're sending back a live blob, not a reference into our backing store. 702 // We're sending back a live blob, not a reference into our backing store.
599 return dispatcher_host_->HoldBlobData(blob_info); 703 return dispatcher_host_->HoldBlobData(blob_info);
600 } 704 }
601 scoped_refptr<ShareableFileReference> shareable_file = 705 scoped_refptr<ShareableFileReference> shareable_file =
602 ShareableFileReference::Get(blob_info.file_path()); 706 ShareableFileReference::Get(blob_info.file_path());
603 if (!shareable_file) { 707 if (!shareable_file) {
604 shareable_file = ShareableFileReference::GetOrCreate( 708 shareable_file = ShareableFileReference::GetOrCreate(
605 blob_info.file_path(), 709 blob_info.file_path(),
606 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE, 710 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
607 dispatcher_host_->context()->TaskRunner()); 711 dispatcher_host_->context()->TaskRunner());
608 if (!blob_info.release_callback().is_null()) 712 if (!blob_info.release_callback().is_null())
609 shareable_file->AddFinalReleaseCallback(blob_info.release_callback()); 713 shareable_file->AddFinalReleaseCallback(blob_info.release_callback());
610 } 714 }
611 return dispatcher_host_->HoldBlobData(blob_info); 715 return dispatcher_host_->HoldBlobData(blob_info);
612 } 716 }
613 717
614 bool IndexedDBCallbacks::IOThreadHelper::CreateAllBlobs( 718 bool IndexedDBCallbacks::IOThreadHelper::CreateAllBlobs(
615 const std::vector<IndexedDBBlobInfo>& blob_info, 719 const std::vector<IndexedDBBlobInfo>& blob_info,
616 std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) { 720 std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) {
721 if (!dispatcher_host_) {
722 OnConnectionError();
723 return false;
724 }
617 IDB_TRACE("IndexedDBCallbacks::CreateAllBlobs"); 725 IDB_TRACE("IndexedDBCallbacks::CreateAllBlobs");
618 DCHECK_EQ(blob_info.size(), blob_or_file_info->size()); 726 DCHECK_EQ(blob_info.size(), blob_or_file_info->size());
619 if (!dispatcher_host_->blob_storage_context()) 727 if (!dispatcher_host_->blob_storage_context())
620 return false; 728 return false;
621 for (size_t i = 0; i < blob_info.size(); ++i) 729 for (size_t i = 0; i < blob_info.size(); ++i)
622 (*blob_or_file_info)[i]->uuid = CreateBlobData(blob_info[i]); 730 (*blob_or_file_info)[i]->uuid = CreateBlobData(blob_info[i]);
623 return true; 731 return true;
624 } 732 }
625 733
626 void IndexedDBCallbacks::IOThreadHelper::OnConnectionError() { 734 void IndexedDBCallbacks::IOThreadHelper::OnConnectionError() {
627 callbacks_.reset(); 735 callbacks_.reset();
628 dispatcher_host_ = nullptr; 736 dispatcher_host_ = nullptr;
629 } 737 }
630 738
631 } // namespace content 739 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698