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..3cd348c5a5a6678ee10b884a95b5f2fc36016799 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) { |
@@ -78,23 +110,26 @@ void ConvertBlobInfo( |
} // namespace |
+// Expected to be created and called from IO thread. |
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 +160,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 +179,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 +198,13 @@ IndexedDBCallbacks::~IndexedDBCallbacks() { |
void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
base::Bind(&IOThreadHelper::SendError, base::Unretained(io_helper_.get()), |
error)); |
- dispatcher_host_ = nullptr; |
+ complete_ = true; |
if (!connection_open_start_time_.is_null()) { |
UMA_HISTOGRAM_MEDIUM_TIMES( |
@@ -179,19 +216,19 @@ void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) { |
void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
base::Bind(&IOThreadHelper::SendSuccessStringList, |
base::Unretained(io_helper_.get()), value)); |
- dispatcher_host_ = nullptr; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::OnBlocked(int64_t existing_version) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
if (sent_blocked_) |
@@ -218,20 +255,19 @@ void IndexedDBCallbacks::OnUpgradeNeeded( |
const IndexedDBDatabaseMetadata& metadata, |
const IndexedDBDataLossInfo& data_loss_info) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
- DCHECK(!database_sent_); |
+ DCHECK(!connection_created_); |
data_loss_ = data_loss_info.status; |
- database_sent_ = true; |
- auto database = base::MakeUnique<DatabaseImpl>(std::move(connection), origin_, |
- dispatcher_host_); |
+ connection_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 +283,25 @@ void IndexedDBCallbacks::OnSuccess( |
std::unique_ptr<IndexedDBConnection> connection, |
const IndexedDBDatabaseMetadata& metadata) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
- DCHECK_EQ(database_sent_, !connection); |
+ DCHECK_EQ(connection_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 one was not previously sent in |
// 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 (!connection_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)); |
+ complete_ = true; |
if (!connection_open_start_time_.is_null()) { |
UMA_HISTOGRAM_MEDIUM_TIMES( |
@@ -281,14 +316,11 @@ void IndexedDBCallbacks::OnSuccess(std::unique_ptr<IndexedDBCursor> cursor, |
const IndexedDBKey& primary_key, |
IndexedDBValue* value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
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 +331,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; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key, |
const IndexedDBKey& primary_key, |
IndexedDBValue* value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
@@ -326,7 +358,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; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::OnSuccessWithPrefetch( |
@@ -334,7 +366,7 @@ void IndexedDBCallbacks::OnSuccessWithPrefetch( |
const std::vector<IndexedDBKey>& primary_keys, |
std::vector<IndexedDBValue>* values) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
DCHECK_EQ(keys.size(), primary_keys.size()); |
DCHECK_EQ(keys.size(), values->size()); |
@@ -351,12 +383,12 @@ void IndexedDBCallbacks::OnSuccessWithPrefetch( |
base::Bind(&IOThreadHelper::SendSuccessCursorPrefetch, |
base::Unretained(io_helper_.get()), keys, primary_keys, |
base::Passed(&mojo_values), *values)); |
- dispatcher_host_ = nullptr; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
@@ -372,13 +404,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; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::OnSuccessArray( |
std::vector<IndexedDBReturnValue>* values) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
@@ -392,12 +424,12 @@ void IndexedDBCallbacks::OnSuccessArray( |
base::Bind(&IOThreadHelper::SendSuccessArray, |
base::Unretained(io_helper_.get()), |
base::Passed(&mojo_values), *values)); |
- dispatcher_host_ = nullptr; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
@@ -406,23 +438,23 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) { |
BrowserThread::IO, FROM_HERE, |
base::Bind(&IOThreadHelper::SendSuccessKey, |
base::Unretained(io_helper_.get()), value)); |
- dispatcher_host_ = nullptr; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::OnSuccess(int64_t value) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
base::Bind(&IOThreadHelper::SendSuccessInteger, |
base::Unretained(io_helper_.get()), value)); |
- dispatcher_host_ = nullptr; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::OnSuccess() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(dispatcher_host_); |
+ DCHECK(!complete_); |
DCHECK(io_helper_); |
DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_); |
@@ -430,7 +462,7 @@ void IndexedDBCallbacks::OnSuccess() { |
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
base::Bind(&IOThreadHelper::SendSuccess, |
base::Unretained(io_helper_.get()))); |
- dispatcher_host_ = nullptr; |
+ complete_ = true; |
} |
void IndexedDBCallbacks::SetConnectionOpenStartTime( |
@@ -440,8 +472,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)); |
@@ -450,70 +486,116 @@ IndexedDBCallbacks::IOThreadHelper::IOThreadHelper( |
} |
} |
-IndexedDBCallbacks::IOThreadHelper::~IOThreadHelper() {} |
+IndexedDBCallbacks::IOThreadHelper::~IOThreadHelper() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+} |
void IndexedDBCallbacks::IOThreadHelper::SendError( |
const IndexedDBDatabaseError& error) { |
- if (callbacks_) |
- callbacks_->Error(error.code(), error.message()); |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ 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); |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ if (!callbacks_) |
+ return; |
+ if (!dispatcher_host_) { |
+ OnConnectionError(); |
+ return; |
+ } |
+ callbacks_->SuccessStringList(value); |
} |
void IndexedDBCallbacks::IOThreadHelper::SendBlocked(int64_t existing_version) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ 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) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
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) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
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) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
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)); |
} |
@@ -521,8 +603,13 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursor( |
void IndexedDBCallbacks::IOThreadHelper::SendSuccessValue( |
::indexed_db::mojom::ReturnValuePtr value, |
const std::vector<IndexedDBBlobInfo>& blob_info) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
if (!callbacks_) |
return; |
+ if (!dispatcher_host_) { |
+ OnConnectionError(); |
+ return; |
+ } |
if (!value || CreateAllBlobs(blob_info, &value->value->blob_or_file_info)) |
callbacks_->SuccessValue(std::move(value)); |
@@ -531,10 +618,15 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessValue( |
void IndexedDBCallbacks::IOThreadHelper::SendSuccessArray( |
std::vector<::indexed_db::mojom::ReturnValuePtr> mojo_values, |
const std::vector<IndexedDBReturnValue>& values) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
DCHECK_EQ(mojo_values.size(), values.size()); |
if (!callbacks_) |
return; |
+ if (!dispatcher_host_) { |
+ OnConnectionError(); |
+ return; |
+ } |
for (size_t i = 0; i < mojo_values.size(); ++i) { |
if (!CreateAllBlobs(values[i].blob_info, |
@@ -549,8 +641,13 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorContinue( |
const IndexedDBKey& primary_key, |
::indexed_db::mojom::ValuePtr value, |
const std::vector<IndexedDBBlobInfo>& blob_info) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
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)); |
@@ -561,10 +658,15 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorPrefetch( |
const std::vector<IndexedDBKey>& primary_keys, |
std::vector<::indexed_db::mojom::ValuePtr> mojo_values, |
const std::vector<IndexedDBValue>& values) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
DCHECK_EQ(mojo_values.size(), values.size()); |
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,22 +680,41 @@ void IndexedDBCallbacks::IOThreadHelper::SendSuccessCursorPrefetch( |
void IndexedDBCallbacks::IOThreadHelper::SendSuccessKey( |
const IndexedDBKey& value) { |
- if (callbacks_) |
- callbacks_->SuccessKey(value); |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ if (!callbacks_) |
+ return; |
+ if (!dispatcher_host_) { |
+ OnConnectionError(); |
+ return; |
+ } |
+ callbacks_->SuccessKey(value); |
} |
void IndexedDBCallbacks::IOThreadHelper::SendSuccessInteger(int64_t value) { |
- if (callbacks_) |
- callbacks_->SuccessInteger(value); |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ if (!callbacks_) |
+ return; |
+ if (!dispatcher_host_) { |
+ OnConnectionError(); |
+ return; |
+ } |
+ callbacks_->SuccessInteger(value); |
} |
void IndexedDBCallbacks::IOThreadHelper::SendSuccess() { |
- if (callbacks_) |
- callbacks_->Success(); |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ if (!callbacks_) |
+ return; |
+ if (!dispatcher_host_) { |
+ OnConnectionError(); |
+ return; |
+ } |
+ callbacks_->Success(); |
} |
std::string IndexedDBCallbacks::IOThreadHelper::CreateBlobData( |
const IndexedDBBlobInfo& blob_info) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
if (!blob_info.uuid().empty()) { |
// We're sending back a live blob, not a reference into our backing store. |
return dispatcher_host_->HoldBlobData(blob_info); |
@@ -614,6 +735,11 @@ 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) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ 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()) |
@@ -624,6 +750,7 @@ bool IndexedDBCallbacks::IOThreadHelper::CreateAllBlobs( |
} |
void IndexedDBCallbacks::IOThreadHelper::OnConnectionError() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
callbacks_.reset(); |
dispatcher_host_ = nullptr; |
} |