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

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

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

Powered by Google App Engine
This is Rietveld 408576698