OLD | NEW |
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 <memory> |
(...skipping 26 matching lines...) Expand all Loading... |
37 #include "storage/browser/quota/quota_manager.h" | 37 #include "storage/browser/quota/quota_manager.h" |
38 | 38 |
39 using indexed_db::mojom::CallbacksAssociatedPtrInfo; | 39 using indexed_db::mojom::CallbacksAssociatedPtrInfo; |
40 using std::swap; | 40 using std::swap; |
41 using storage::ShareableFileReference; | 41 using storage::ShareableFileReference; |
42 | 42 |
43 namespace content { | 43 namespace content { |
44 | 44 |
45 namespace { | 45 namespace { |
46 | 46 |
47 // If this is destructed with the connection still living inside it, we assume | 47 // The following two objects protect the given objects from being destructed on |
48 // we have been killed due to IO thread shutdown, and we need to safely schedule | 48 // the IO thread if we have a shutdown or an error. |
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 { | 49 struct SafeIOThreadConnectionWrapper { |
52 SafeIOThreadConnectionWrapper(std::unique_ptr<IndexedDBConnection> connection) | 50 SafeIOThreadConnectionWrapper(std::unique_ptr<IndexedDBConnection> connection) |
53 : connection(std::move(connection)), | 51 : connection(std::move(connection)), |
54 idb_runner(base::ThreadTaskRunnerHandle::Get()) {} | 52 idb_runner(base::ThreadTaskRunnerHandle::Get()) {} |
55 ~SafeIOThreadConnectionWrapper() { | 53 ~SafeIOThreadConnectionWrapper() { |
56 if (connection) { | 54 if (connection) { |
57 idb_runner->PostTask( | 55 idb_runner->PostTask( |
58 FROM_HERE, base::Bind( | 56 FROM_HERE, base::Bind( |
59 [](std::unique_ptr<IndexedDBConnection> connection) { | 57 [](std::unique_ptr<IndexedDBConnection> connection) { |
60 connection->ForceClose(); | 58 connection->ForceClose(); |
61 }, | 59 }, |
62 base::Passed(&connection))); | 60 base::Passed(&connection))); |
63 } | 61 } |
64 } | 62 } |
65 SafeIOThreadConnectionWrapper(SafeIOThreadConnectionWrapper&& other) = | 63 SafeIOThreadConnectionWrapper(SafeIOThreadConnectionWrapper&& other) = |
66 default; | 64 default; |
67 | 65 |
68 std::unique_ptr<IndexedDBConnection> connection; | 66 std::unique_ptr<IndexedDBConnection> connection; |
69 scoped_refptr<base::SequencedTaskRunner> idb_runner; | 67 scoped_refptr<base::SequencedTaskRunner> idb_runner; |
70 | 68 |
71 private: | 69 private: |
72 DISALLOW_COPY_AND_ASSIGN(SafeIOThreadConnectionWrapper); | 70 DISALLOW_COPY_AND_ASSIGN(SafeIOThreadConnectionWrapper); |
73 }; | 71 }; |
74 | 72 |
| 73 struct SafeIOThreadCursorWrapper { |
| 74 SafeIOThreadCursorWrapper(std::unique_ptr<IndexedDBCursor> cursor) |
| 75 : cursor(std::move(cursor)), |
| 76 idb_runner(base::ThreadTaskRunnerHandle::Get()) {} |
| 77 ~SafeIOThreadCursorWrapper() { |
| 78 if (cursor) |
| 79 idb_runner->DeleteSoon(FROM_HERE, cursor.release()); |
| 80 } |
| 81 SafeIOThreadCursorWrapper(SafeIOThreadCursorWrapper&& other) = default; |
| 82 |
| 83 std::unique_ptr<IndexedDBCursor> cursor; |
| 84 scoped_refptr<base::SequencedTaskRunner> idb_runner; |
| 85 |
| 86 private: |
| 87 DISALLOW_COPY_AND_ASSIGN(SafeIOThreadCursorWrapper); |
| 88 }; |
| 89 |
75 void ConvertBlobInfo( | 90 void ConvertBlobInfo( |
76 const std::vector<IndexedDBBlobInfo>& blob_info, | 91 const std::vector<IndexedDBBlobInfo>& blob_info, |
77 std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) { | 92 std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) { |
78 blob_or_file_info->reserve(blob_info.size()); | 93 blob_or_file_info->reserve(blob_info.size()); |
79 for (const auto& iter : blob_info) { | 94 for (const auto& iter : blob_info) { |
80 if (!iter.mark_used_callback().is_null()) | 95 if (!iter.mark_used_callback().is_null()) |
81 iter.mark_used_callback().Run(); | 96 iter.mark_used_callback().Run(); |
82 | 97 |
83 auto info = ::indexed_db::mojom::BlobInfo::New(); | 98 auto info = ::indexed_db::mojom::BlobInfo::New(); |
84 info->mime_type = iter.type(); | 99 info->mime_type = iter.type(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 void SendError(const IndexedDBDatabaseError& error); | 137 void SendError(const IndexedDBDatabaseError& error); |
123 void SendSuccessStringList(const std::vector<base::string16>& value); | 138 void SendSuccessStringList(const std::vector<base::string16>& value); |
124 void SendBlocked(int64_t existing_version); | 139 void SendBlocked(int64_t existing_version); |
125 void SendUpgradeNeeded(SafeIOThreadConnectionWrapper connection, | 140 void SendUpgradeNeeded(SafeIOThreadConnectionWrapper connection, |
126 int64_t old_version, | 141 int64_t old_version, |
127 blink::WebIDBDataLoss data_loss, | 142 blink::WebIDBDataLoss data_loss, |
128 const std::string& data_loss_message, | 143 const std::string& data_loss_message, |
129 const content::IndexedDBDatabaseMetadata& metadata); | 144 const content::IndexedDBDatabaseMetadata& metadata); |
130 void SendSuccessDatabase(SafeIOThreadConnectionWrapper connection, | 145 void SendSuccessDatabase(SafeIOThreadConnectionWrapper connection, |
131 const content::IndexedDBDatabaseMetadata& metadata); | 146 const content::IndexedDBDatabaseMetadata& metadata); |
132 void SendSuccessCursor(std::unique_ptr<IndexedDBCursor> cursor, | 147 void SendSuccessCursor(SafeIOThreadCursorWrapper cursor, |
133 const IndexedDBKey& key, | 148 const IndexedDBKey& key, |
134 const IndexedDBKey& primary_key, | 149 const IndexedDBKey& primary_key, |
135 ::indexed_db::mojom::ValuePtr value, | 150 ::indexed_db::mojom::ValuePtr value, |
136 const std::vector<IndexedDBBlobInfo>& blob_info); | 151 const std::vector<IndexedDBBlobInfo>& blob_info); |
137 void SendSuccessValue(::indexed_db::mojom::ReturnValuePtr value, | 152 void SendSuccessValue(::indexed_db::mojom::ReturnValuePtr value, |
138 const std::vector<IndexedDBBlobInfo>& blob_info); | 153 const std::vector<IndexedDBBlobInfo>& blob_info); |
139 void SendSuccessCursorContinue( | 154 void SendSuccessCursorContinue( |
140 const IndexedDBKey& key, | 155 const IndexedDBKey& key, |
141 const IndexedDBKey& primary_key, | 156 const IndexedDBKey& primary_key, |
142 ::indexed_db::mojom::ValuePtr value, | 157 ::indexed_db::mojom::ValuePtr value, |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 | 336 |
322 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); | 337 DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
323 | 338 |
324 ::indexed_db::mojom::ValuePtr mojo_value; | 339 ::indexed_db::mojom::ValuePtr mojo_value; |
325 std::vector<IndexedDBBlobInfo> blob_info; | 340 std::vector<IndexedDBBlobInfo> blob_info; |
326 if (value) { | 341 if (value) { |
327 mojo_value = ConvertAndEraseValue(value); | 342 mojo_value = ConvertAndEraseValue(value); |
328 blob_info.swap(value->blob_info); | 343 blob_info.swap(value->blob_info); |
329 } | 344 } |
330 | 345 |
| 346 SafeIOThreadCursorWrapper cursor_wrapper(std::move(cursor)); |
| 347 |
331 BrowserThread::PostTask( | 348 BrowserThread::PostTask( |
332 BrowserThread::IO, FROM_HERE, | 349 BrowserThread::IO, FROM_HERE, |
333 base::Bind(&IOThreadHelper::SendSuccessCursor, | 350 base::Bind(&IOThreadHelper::SendSuccessCursor, |
334 base::Unretained(io_helper_.get()), base::Passed(&cursor), key, | 351 base::Unretained(io_helper_.get()), |
335 primary_key, base::Passed(&mojo_value), | 352 base::Passed(&cursor_wrapper), key, primary_key, |
336 base::Passed(&blob_info))); | 353 base::Passed(&mojo_value), base::Passed(&blob_info))); |
337 complete_ = true; | 354 complete_ = true; |
338 } | 355 } |
339 | 356 |
340 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, | 357 void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, |
341 const IndexedDBKey& primary_key, | 358 const IndexedDBKey& primary_key, |
342 IndexedDBValue* value) { | 359 IndexedDBValue* value) { |
343 DCHECK(thread_checker_.CalledOnValidThread()); | 360 DCHECK(thread_checker_.CalledOnValidThread()); |
344 DCHECK(!complete_); | 361 DCHECK(!complete_); |
345 DCHECK(io_helper_); | 362 DCHECK(io_helper_); |
346 | 363 |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 dispatcher_host_.get(), idb_runner_); | 584 dispatcher_host_.get(), idb_runner_); |
568 | 585 |
569 auto request = mojo::MakeRequest(&ptr_info); | 586 auto request = mojo::MakeRequest(&ptr_info); |
570 dispatcher_host_->AddDatabaseBinding(std::move(database), | 587 dispatcher_host_->AddDatabaseBinding(std::move(database), |
571 std::move(request)); | 588 std::move(request)); |
572 } | 589 } |
573 callbacks_->SuccessDatabase(std::move(ptr_info), metadata); | 590 callbacks_->SuccessDatabase(std::move(ptr_info), metadata); |
574 } | 591 } |
575 | 592 |
576 void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor( | 593 void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor( |
577 std::unique_ptr<IndexedDBCursor> cursor, | 594 SafeIOThreadCursorWrapper cursor, |
578 const IndexedDBKey& key, | 595 const IndexedDBKey& key, |
579 const IndexedDBKey& primary_key, | 596 const IndexedDBKey& primary_key, |
580 ::indexed_db::mojom::ValuePtr value, | 597 ::indexed_db::mojom::ValuePtr value, |
581 const std::vector<IndexedDBBlobInfo>& blob_info) { | 598 const std::vector<IndexedDBBlobInfo>& blob_info) { |
582 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 599 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
583 if (!callbacks_) | 600 if (!callbacks_) |
584 return; | 601 return; |
585 if (!dispatcher_host_) { | 602 if (!dispatcher_host_) { |
586 OnConnectionError(); | 603 OnConnectionError(); |
587 return; | 604 return; |
588 } | 605 } |
589 auto cursor_impl = base::MakeUnique<CursorImpl>( | 606 auto cursor_impl = base::MakeUnique<CursorImpl>( |
590 std::move(cursor), origin_, dispatcher_host_.get(), idb_runner_); | 607 std::move(cursor.cursor), origin_, dispatcher_host_.get(), idb_runner_); |
591 | 608 |
592 if (value && !CreateAllBlobs(blob_info, &value->blob_or_file_info)) | 609 if (value && !CreateAllBlobs(blob_info, &value->blob_or_file_info)) |
593 return; | 610 return; |
594 | 611 |
595 ::indexed_db::mojom::CursorAssociatedPtrInfo ptr_info; | 612 ::indexed_db::mojom::CursorAssociatedPtrInfo ptr_info; |
596 auto request = mojo::MakeRequest(&ptr_info); | 613 auto request = mojo::MakeRequest(&ptr_info); |
597 dispatcher_host_->AddCursorBinding(std::move(cursor_impl), | 614 dispatcher_host_->AddCursorBinding(std::move(cursor_impl), |
598 std::move(request)); | 615 std::move(request)); |
599 callbacks_->SuccessCursor(std::move(ptr_info), key, primary_key, | 616 callbacks_->SuccessCursor(std::move(ptr_info), key, primary_key, |
600 std::move(value)); | 617 std::move(value)); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 return true; | 766 return true; |
750 } | 767 } |
751 | 768 |
752 void IndexedDBCallbacks::IOThreadHelper::OnConnectionError() { | 769 void IndexedDBCallbacks::IOThreadHelper::OnConnectionError() { |
753 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 770 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
754 callbacks_.reset(); | 771 callbacks_.reset(); |
755 dispatcher_host_ = nullptr; | 772 dispatcher_host_ = nullptr; |
756 } | 773 } |
757 | 774 |
758 } // namespace content | 775 } // namespace content |
OLD | NEW |