Chromium Code Reviews| Index: content/browser/indexed_db/indexed_db_callbacks.cc |
| diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc |
| index ceb8e1318e7fa47d39238e1276b0922c649421a3..087f7713f28fbe1d4ebcc52db3d6aeec1dbea3a3 100644 |
| --- a/content/browser/indexed_db/indexed_db_callbacks.cc |
| +++ b/content/browser/indexed_db/indexed_db_callbacks.cc |
| @@ -7,11 +7,14 @@ |
| #include <stddef.h> |
| #include <algorithm> |
| +#include <memory> |
| #include <utility> |
| #include "base/memory/ptr_util.h" |
| #include "base/metrics/histogram_macros.h" |
| +#include "base/sequenced_task_runner.h" |
| #include "base/strings/utf_string_conversions.h" |
| +#include "base/threading/thread_task_runner_handle.h" |
| #include "base/time/time.h" |
| #include "content/browser/child_process_security_policy_impl.h" |
| #include "content/browser/fileapi/fileapi_message_filter.h" |
| @@ -27,6 +30,7 @@ |
| #include "content/browser/indexed_db/indexed_db_value.h" |
| #include "content/common/indexed_db/indexed_db_constants.h" |
| #include "content/common/indexed_db/indexed_db_metadata.h" |
| +#include "content/public/browser/browser_thread.h" |
| #include "mojo/public/cpp/bindings/strong_associated_binding.h" |
| #include "storage/browser/blob/blob_storage_context.h" |
| #include "storage/browser/blob/shareable_file_reference.h" |
| @@ -40,6 +44,34 @@ namespace content { |
| namespace { |
| +// If this is destructed with the connection still living inside it, we assume |
| +// we have been killed due to IO thread shutdown, and we need to safely schedule |
| +// the destruction of the connection on the IDB thread, as we should still be in |
| +// a transaction's operation queue, where we cannot destroy the transaction. |
| +struct SafeIOThreadConnectionWrapper { |
| + SafeIOThreadConnectionWrapper(std::unique_ptr<IndexedDBConnection> connection) |
| + : connection(std::move(connection)), |
| + idb_runner(base::ThreadTaskRunnerHandle::Get()) {} |
| + ~SafeIOThreadConnectionWrapper() { |
| + if (connection) { |
| + idb_runner->PostTask( |
| + FROM_HERE, base::Bind( |
| + [](std::unique_ptr<IndexedDBConnection> connection) { |
| + connection->ForceClose(); |
| + }, |
| + base::Passed(&connection))); |
| + } |
| + } |
| + SafeIOThreadConnectionWrapper(SafeIOThreadConnectionWrapper&& other) = |
| + default; |
| + |
| + std::unique_ptr<IndexedDBConnection> connection; |
| + scoped_refptr<base::SequencedTaskRunner> idb_runner; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(SafeIOThreadConnectionWrapper); |
| +}; |
| + |
| void ConvertBlobInfo( |
| const std::vector<IndexedDBBlobInfo>& blob_info, |
| std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) { |
| @@ -81,20 +113,22 @@ void ConvertBlobInfo( |
| class IndexedDBCallbacks::IOThreadHelper { |
| public: |
| IOThreadHelper(CallbacksAssociatedPtrInfo callbacks_info, |
| - scoped_refptr<IndexedDBDispatcherHost> dispatcher_host); |
| + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, |
| + url::Origin origin, |
| + scoped_refptr<base::SequencedTaskRunner> idb_runner); |
| ~IOThreadHelper(); |
| void SendError(const IndexedDBDatabaseError& error); |
| void SendSuccessStringList(const std::vector<base::string16>& value); |
| void SendBlocked(int64_t existing_version); |
| - void SendUpgradeNeeded(std::unique_ptr<DatabaseImpl> database, |
| + void SendUpgradeNeeded(SafeIOThreadConnectionWrapper connection, |
| int64_t old_version, |
| blink::WebIDBDataLoss data_loss, |
| const std::string& data_loss_message, |
| const content::IndexedDBDatabaseMetadata& metadata); |
| - void SendSuccessDatabase(std::unique_ptr<DatabaseImpl> database, |
| + void SendSuccessDatabase(SafeIOThreadConnectionWrapper connection, |
| const content::IndexedDBDatabaseMetadata& metadata); |
| - void SendSuccessCursor(std::unique_ptr<CursorImpl> cursor, |
| + void SendSuccessCursor(std::unique_ptr<IndexedDBCursor> cursor, |
| const IndexedDBKey& key, |
| const IndexedDBKey& primary_key, |
| ::indexed_db::mojom::ValuePtr value, |
| @@ -125,8 +159,10 @@ class IndexedDBCallbacks::IOThreadHelper { |
| void OnConnectionError(); |
| private: |
| - scoped_refptr<IndexedDBDispatcherHost> dispatcher_host_; |
| + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host_; |
| ::indexed_db::mojom::CallbacksAssociatedPtr callbacks_; |
| + url::Origin origin_; |
| + scoped_refptr<base::SequencedTaskRunner> idb_runner_; |
| DISALLOW_COPY_AND_ASSIGN(IOThreadHelper); |
| }; |
| @@ -142,15 +178,15 @@ class IndexedDBCallbacks::IOThreadHelper { |
| } |
| IndexedDBCallbacks::IndexedDBCallbacks( |
| - scoped_refptr<IndexedDBDispatcherHost> dispatcher_host, |
| + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, |
| const url::Origin& origin, |
| - ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) |
| - : dispatcher_host_(std::move(dispatcher_host)), |
| - origin_(origin), |
| - data_loss_(blink::kWebIDBDataLossNone), |
| - sent_blocked_(false), |
| - io_helper_( |
| - new IOThreadHelper(std::move(callbacks_info), dispatcher_host_)) { |
| + ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info, |
| + scoped_refptr<base::SequencedTaskRunner> idb_runner) |
| + : data_loss_(blink::kWebIDBDataLossNone), |
| + io_helper_(new IOThreadHelper(std::move(callbacks_info), |
| + std::move(dispatcher_host), |
| + origin, |
| + std::move(idb_runner))) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| thread_checker_.DetachFromThread(); |
| } |
| @@ -161,13 +197,13 @@ IndexedDBCallbacks::~IndexedDBCallbacks() { |
| void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind(&IOThreadHelper::SendError, base::Unretained(io_helper_.get()), |
| error)); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| if (!connection_open_start_time_.is_null()) { |
| UMA_HISTOGRAM_MEDIUM_TIMES( |
| @@ -179,19 +215,19 @@ void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) { |
| void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind(&IOThreadHelper::SendSuccessStringList, |
| base::Unretained(io_helper_.get()), value)); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::OnBlocked(int64_t existing_version) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| if (sent_blocked_) |
| @@ -218,20 +254,19 @@ void IndexedDBCallbacks::OnUpgradeNeeded( |
| const IndexedDBDatabaseMetadata& metadata, |
| const IndexedDBDataLossInfo& data_loss_info) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| - DCHECK(!database_sent_); |
| + 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.
|
| data_loss_ = data_loss_info.status; |
| - database_sent_ = true; |
| - auto database = base::MakeUnique<DatabaseImpl>(std::move(connection), origin_, |
| - dispatcher_host_); |
| + database_created_ = true; |
| + SafeIOThreadConnectionWrapper wrapper(std::move(connection)); |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind(&IOThreadHelper::SendUpgradeNeeded, |
| - base::Unretained(io_helper_.get()), base::Passed(&database), |
| + base::Unretained(io_helper_.get()), base::Passed(&wrapper), |
| old_version, data_loss_info.status, data_loss_info.message, |
| metadata)); |
| @@ -247,26 +282,25 @@ void IndexedDBCallbacks::OnSuccess( |
| std::unique_ptr<IndexedDBConnection> connection, |
| const IndexedDBDatabaseMetadata& metadata) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| - DCHECK_EQ(database_sent_, !connection); |
| + DCHECK_EQ(database_created_, !connection); |
| scoped_refptr<IndexedDBCallbacks> self(this); |
| - // Only send a new Database if the connection was not previously sent in |
| + // 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.
|
| // OnUpgradeNeeded. |
| - std::unique_ptr<DatabaseImpl> database; |
| - if (!database_sent_) { |
| - database.reset( |
| - new DatabaseImpl(std::move(connection), origin_, dispatcher_host_)); |
| - } |
| + std::unique_ptr<IndexedDBConnection> database_connection; |
| + if (!database_created_) |
| + database_connection = std::move(connection); |
| + SafeIOThreadConnectionWrapper wrapper(std::move(database_connection)); |
| BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| base::Bind(&IOThreadHelper::SendSuccessDatabase, |
| base::Unretained(io_helper_.get()), |
| - base::Passed(&database), metadata)); |
| - dispatcher_host_ = nullptr; |
| + base::Passed(&wrapper), metadata)); |
| + 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.
|
| if (!connection_open_start_time_.is_null()) { |
| UMA_HISTOGRAM_MEDIUM_TIMES( |
| @@ -281,14 +315,11 @@ void IndexedDBCallbacks::OnSuccess(std::unique_ptr<IndexedDBCursor> cursor, |
| const IndexedDBKey& primary_key, |
| IndexedDBValue* value) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
| - auto cursor_impl = base::MakeUnique<CursorImpl>(std::move(cursor), origin_, |
| - dispatcher_host_); |
| - |
| ::indexed_db::mojom::ValuePtr mojo_value; |
| std::vector<IndexedDBBlobInfo> blob_info; |
| if (value) { |
| @@ -299,17 +330,17 @@ void IndexedDBCallbacks::OnSuccess(std::unique_ptr<IndexedDBCursor> cursor, |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind(&IOThreadHelper::SendSuccessCursor, |
| - base::Unretained(io_helper_.get()), base::Passed(&cursor_impl), |
| - key, primary_key, base::Passed(&mojo_value), |
| + base::Unretained(io_helper_.get()), base::Passed(&cursor), key, |
| + primary_key, base::Passed(&mojo_value), |
| base::Passed(&blob_info))); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, |
| const IndexedDBKey& primary_key, |
| IndexedDBValue* value) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
| @@ -326,7 +357,7 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, |
| base::Bind(&IOThreadHelper::SendSuccessCursorContinue, |
| base::Unretained(io_helper_.get()), key, primary_key, |
| base::Passed(&mojo_value), base::Passed(&blob_info))); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::OnSuccessWithPrefetch( |
| @@ -334,7 +365,7 @@ void IndexedDBCallbacks::OnSuccessWithPrefetch( |
| const std::vector<IndexedDBKey>& primary_keys, |
| std::vector<IndexedDBValue>* values) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| DCHECK_EQ(keys.size(), primary_keys.size()); |
| DCHECK_EQ(keys.size(), values->size()); |
| @@ -351,12 +382,12 @@ void IndexedDBCallbacks::OnSuccessWithPrefetch( |
| base::Bind(&IOThreadHelper::SendSuccessCursorPrefetch, |
| base::Unretained(io_helper_.get()), keys, primary_keys, |
| base::Passed(&mojo_values), *values)); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
| @@ -372,13 +403,13 @@ void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) { |
| base::Bind(&IOThreadHelper::SendSuccessValue, |
| base::Unretained(io_helper_.get()), base::Passed(&mojo_value), |
| base::Passed(&blob_info))); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::OnSuccessArray( |
| std::vector<IndexedDBReturnValue>* values) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
| @@ -392,12 +423,12 @@ void IndexedDBCallbacks::OnSuccessArray( |
| base::Bind(&IOThreadHelper::SendSuccessArray, |
| base::Unretained(io_helper_.get()), |
| base::Passed(&mojo_values), *values)); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
| @@ -406,23 +437,23 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { |
| BrowserThread::IO, FROM_HERE, |
| base::Bind(&IOThreadHelper::SendSuccessKey, |
| base::Unretained(io_helper_.get()), value)); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::OnSuccess(int64_t value) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind(&IOThreadHelper::SendSuccessInteger, |
| base::Unretained(io_helper_.get()), value)); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::OnSuccess() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - DCHECK(dispatcher_host_); |
| + DCHECK(!closed_); |
| DCHECK(io_helper_); |
| DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
| @@ -430,7 +461,7 @@ void IndexedDBCallbacks::OnSuccess() { |
| BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| base::Bind(&IOThreadHelper::SendSuccess, |
| base::Unretained(io_helper_.get()))); |
| - dispatcher_host_ = nullptr; |
| + closed_ = true; |
| } |
| void IndexedDBCallbacks::SetConnectionOpenStartTime( |
| @@ -440,8 +471,12 @@ void IndexedDBCallbacks::SetConnectionOpenStartTime( |
| IndexedDBCallbacks::IOThreadHelper::IOThreadHelper( |
| CallbacksAssociatedPtrInfo callbacks_info, |
| - scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) |
| - : dispatcher_host_(std::move(dispatcher_host)) { |
| + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, |
| + url::Origin origin, |
| + scoped_refptr<base::SequencedTaskRunner> idb_runner) |
| + : dispatcher_host_(std::move(dispatcher_host)), |
| + origin_(origin), |
| + idb_runner_(idb_runner) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| if (callbacks_info.is_valid()) { |
| callbacks_.Bind(std::move(callbacks_info)); |
| @@ -454,66 +489,104 @@ IndexedDBCallbacks::IOThreadHelper::~IOThreadHelper() {} |
| void IndexedDBCallbacks::IOThreadHelper::SendError( |
| const IndexedDBDatabaseError& error) { |
| - if (callbacks_) |
| - callbacks_->Error(error.code(), error.message()); |
| + if (!callbacks_) |
| + return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| + callbacks_->Error(error.code(), error.message()); |
| } |
| void IndexedDBCallbacks::IOThreadHelper::SendSuccessStringList( |
| const std::vector<base::string16>& value) { |
| - if (callbacks_) |
| - callbacks_->SuccessStringList(value); |
| + if (!callbacks_) |
| + return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| + callbacks_->SuccessStringList(value); |
| } |
| void IndexedDBCallbacks::IOThreadHelper::SendBlocked(int64_t existing_version) { |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| if (callbacks_) |
| callbacks_->Blocked(existing_version); |
| } |
| void IndexedDBCallbacks::IOThreadHelper::SendUpgradeNeeded( |
| - std::unique_ptr<DatabaseImpl> database, |
| + SafeIOThreadConnectionWrapper connection_wrapper, |
| int64_t old_version, |
| blink::WebIDBDataLoss data_loss, |
| const std::string& data_loss_message, |
| const content::IndexedDBDatabaseMetadata& metadata) { |
| if (!callbacks_) |
| return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| + |
| + auto database = base::MakeUnique<DatabaseImpl>( |
| + std::move(connection_wrapper.connection), origin_, dispatcher_host_.get(), |
| + idb_runner_); |
| ::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info; |
| auto request = mojo::MakeRequest(&ptr_info); |
| - mojo::MakeStrongAssociatedBinding(std::move(database), std::move(request)); |
| + |
| + dispatcher_host_->AddDatabaseBinding(std::move(database), std::move(request)); |
| callbacks_->UpgradeNeeded(std::move(ptr_info), old_version, data_loss, |
| data_loss_message, metadata); |
| } |
| void IndexedDBCallbacks::IOThreadHelper::SendSuccessDatabase( |
| - std::unique_ptr<DatabaseImpl> database, |
| + SafeIOThreadConnectionWrapper connection_wrapper, |
| const content::IndexedDBDatabaseMetadata& metadata) { |
| if (!callbacks_) |
| return; |
| - |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| ::indexed_db::mojom::DatabaseAssociatedPtrInfo ptr_info; |
| - if (database) { |
| + if (connection_wrapper.connection) { |
| + auto database = base::MakeUnique<DatabaseImpl>( |
| + std::move(connection_wrapper.connection), origin_, |
| + dispatcher_host_.get(), idb_runner_); |
| + |
| auto request = mojo::MakeRequest(&ptr_info); |
| - mojo::MakeStrongAssociatedBinding(std::move(database), std::move(request)); |
| + dispatcher_host_->AddDatabaseBinding(std::move(database), |
| + std::move(request)); |
| } |
| callbacks_->SuccessDatabase(std::move(ptr_info), metadata); |
| } |
| void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor( |
| - std::unique_ptr<CursorImpl> cursor, |
| + std::unique_ptr<IndexedDBCursor> cursor, |
| const IndexedDBKey& key, |
| const IndexedDBKey& primary_key, |
| ::indexed_db::mojom::ValuePtr value, |
| const std::vector<IndexedDBBlobInfo>& blob_info) { |
| if (!callbacks_) |
| return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| + auto cursor_impl = base::MakeUnique<CursorImpl>( |
| + std::move(cursor), origin_, dispatcher_host_.get(), idb_runner_); |
| if (value && !CreateAllBlobs(blob_info, &value->blob_or_file_info)) |
| return; |
| ::indexed_db::mojom::CursorAssociatedPtrInfo ptr_info; |
| auto request = mojo::MakeRequest(&ptr_info); |
| - mojo::MakeStrongAssociatedBinding(std::move(cursor), std::move(request)); |
| + dispatcher_host_->AddCursorBinding(std::move(cursor_impl), |
| + std::move(request)); |
| callbacks_->SuccessCursor(std::move(ptr_info), key, primary_key, |
| std::move(value)); |
| } |
| @@ -523,6 +596,10 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessValue( |
| const std::vector<IndexedDBBlobInfo>& blob_info) { |
| if (!callbacks_) |
| return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| if (!value || CreateAllBlobs(blob_info, &value->value->blob_or_file_info)) |
| callbacks_->SuccessValue(std::move(value)); |
| @@ -535,6 +612,10 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessArray( |
| if (!callbacks_) |
| return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| for (size_t i = 0; i < mojo_values.size(); ++i) { |
| if (!CreateAllBlobs(values[i].blob_info, |
| @@ -551,6 +632,10 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorContinue( |
| const std::vector<IndexedDBBlobInfo>& blob_info) { |
| if (!callbacks_) |
| return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| if (!value || CreateAllBlobs(blob_info, &value->blob_or_file_info)) |
| callbacks_->SuccessCursorContinue(key, primary_key, std::move(value)); |
| @@ -565,6 +650,10 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorPrefetch( |
| if (!callbacks_) |
| return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| for (size_t i = 0; i < mojo_values.size(); ++i) { |
| if (!CreateAllBlobs(values[i].blob_info, |
| @@ -578,18 +667,33 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorPrefetch( |
| void IndexedDBCallbacks::IOThreadHelper::SendSuccessKey( |
| const IndexedDBKey& value) { |
| - if (callbacks_) |
| - callbacks_->SuccessKey(value); |
| + if (!callbacks_) |
| + return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| + callbacks_->SuccessKey(value); |
| } |
| void IndexedDBCallbacks::IOThreadHelper::SendSuccessInteger(int64_t value) { |
| - if (callbacks_) |
| - callbacks_->SuccessInteger(value); |
| + if (!callbacks_) |
| + return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| + callbacks_->SuccessInteger(value); |
| } |
| void IndexedDBCallbacks::IOThreadHelper::SendSuccess() { |
| - if (callbacks_) |
| - callbacks_->Success(); |
| + if (!callbacks_) |
| + return; |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return; |
| + } |
| + callbacks_->Success(); |
| } |
| std::string IndexedDBCallbacks::IOThreadHelper::CreateBlobData( |
| @@ -614,6 +718,10 @@ std::string IndexedDBCallbacks::IOThreadHelper::CreateBlobData( |
| bool IndexedDBCallbacks::IOThreadHelper::CreateAllBlobs( |
| const std::vector<IndexedDBBlobInfo>& blob_info, |
| std::vector<::indexed_db::mojom::BlobInfoPtr>* blob_or_file_info) { |
| + if (!dispatcher_host_) { |
| + OnConnectionError(); |
| + return false; |
| + } |
| IDB_TRACE("IndexedDBCallbacks::CreateAllBlobs"); |
| DCHECK_EQ(blob_info.size(), blob_or_file_info->size()); |
| if (!dispatcher_host_->blob_storage_context()) |