Commit 6d016c93 authored by stanisc's avatar stanisc Committed by Commit Bot

Migrate Extensions Store/Policy code to Task Scheduler API

This changes most of Extensions Store/Policy code to use a dedicated
SequencedTaskRunner to post tasks rather than posting on the browser
FILE thread.

Initially I tried to keep the change limited to the sync related
part of the Extensions code. The problem that I ran into is that
different types of storage are handled in a generic way on the
storage frontend (for example, all them were deleted on FILE thread).
So once I migrated the sync storage, I had to modify other storage
types as well. Because of that I had to access backend task
runner singleton from extensions component so in order to satisfy
dependencies I had to move GetBackendTaskRunner() to
extensions/browser/api/storage.

Some of the tests relied on TestBrowserThreadBundle making all
browser threads map to the same physical thread which allowed the
test code to satisfy DCHECK_CURRENTLY_ON(BrowserThread::FILE) check
while running on the main test thread. With this migration that
didn't work anymore so I had to modify ExtensionSettingSyncTest and
PolicyValueStoreTest tests to actually post API calls on the right
sequence. That was the most difficult part of this change.
Other than that the rest of the changes should be straightforward.

BUG=689520

Review-Url: https://codereview.chromium.org/2965153002
Cr-Commit-Position: refs/heads/master@{#486250}
parent 65f31455
......@@ -374,8 +374,6 @@ static_library("extensions") {
"api/signed_in_devices/signed_in_devices_manager.h",
"api/spellcheck/spellcheck_api.cc",
"api/spellcheck/spellcheck_api.h",
"api/storage/backend_task_runner.cc",
"api/storage/backend_task_runner.h",
"api/storage/managed_value_store_cache.cc",
"api/storage/managed_value_store_cache.h",
"api/storage/policy_value_store.cc",
......
......@@ -26,6 +26,7 @@
#include "components/policy/core/common/schema_map.h"
#include "components/policy/core/common/schema_registry.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
......@@ -259,7 +260,7 @@ ManagedValueStoreCache::ManagedValueStoreCache(
}
ManagedValueStoreCache::~ManagedValueStoreCache() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
// Delete the PolicyValueStores on FILE.
store_map_.clear();
}
......@@ -273,13 +274,13 @@ void ManagedValueStoreCache::ShutdownOnUI() {
void ManagedValueStoreCache::RunWithValueStoreForExtension(
const StorageCallback& callback,
scoped_refptr<const Extension> extension) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
callback.Run(GetStoreFor(extension->id()));
}
void ManagedValueStoreCache::DeleteStorageSoon(
const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
// It's possible that the store exists, but hasn't been loaded yet
// (because the extension is unloaded, for example). Open the database to
// clear it if it exists.
......@@ -327,11 +328,10 @@ void ManagedValueStoreCache::OnPolicyUpdated(const policy::PolicyNamespace& ns,
return;
}
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::BindOnce(&ManagedValueStoreCache::UpdatePolicyOnFILE,
base::Unretained(this), ns.component_id,
base::Passed(current.DeepCopy())));
GetBackendTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&ManagedValueStoreCache::UpdatePolicyOnBackend,
base::Unretained(this), ns.component_id,
base::Passed(current.DeepCopy())));
}
// static
......@@ -345,10 +345,10 @@ policy::PolicyDomain ManagedValueStoreCache::GetPolicyDomain(Profile* profile) {
#endif
}
void ManagedValueStoreCache::UpdatePolicyOnFILE(
void ManagedValueStoreCache::UpdatePolicyOnBackend(
const std::string& extension_id,
std::unique_ptr<policy::PolicyMap> current_policy) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
if (!HasStore(extension_id) && current_policy->empty()) {
// Don't create the store now if there are no policies configured for this
......@@ -362,7 +362,7 @@ void ManagedValueStoreCache::UpdatePolicyOnFILE(
PolicyValueStore* ManagedValueStoreCache::GetStoreFor(
const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
auto it = store_map_.find(extension_id);
if (it != store_map_.end())
......
......@@ -67,10 +67,10 @@ class ManagedValueStoreCache : public ValueStoreCache,
// Returns the policy domain that should be used for the specified profile.
static policy::PolicyDomain GetPolicyDomain(Profile* profile);
// Posted by OnPolicyUpdated() to update a PolicyValueStore on the FILE
// thread.
void UpdatePolicyOnFILE(const std::string& extension_id,
std::unique_ptr<policy::PolicyMap> current_policy);
// Posted by OnPolicyUpdated() to update a PolicyValueStore on the backend
// sequence.
void UpdatePolicyOnBackend(const std::string& extension_id,
std::unique_ptr<policy::PolicyMap> current_policy);
// Returns an existing PolicyValueStore for |extension_id|, or NULL.
PolicyValueStore* GetStoreFor(const std::string& extension_id);
......
......@@ -10,12 +10,10 @@
#include "base/values.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/settings_namespace.h"
#include "extensions/browser/value_store/value_store_change.h"
using content::BrowserThread;
namespace extensions {
namespace {
......@@ -38,7 +36,7 @@ PolicyValueStore::PolicyValueStore(
PolicyValueStore::~PolicyValueStore() {}
void PolicyValueStore::SetCurrentPolicy(const policy::PolicyMap& policy) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
// Convert |policy| to a dictionary value. Only include mandatory policies
// for now.
base::DictionaryValue current_policy;
......
......@@ -12,11 +12,12 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/settings_observer.h"
#include "extensions/browser/value_store/leveldb_value_store.h"
#include "extensions/browser/value_store/value_store_unittest.h"
......@@ -111,6 +112,20 @@ class PolicyValueStoreTest : public testing::Test {
}
protected:
void SetCurrentPolicy(const policy::PolicyMap& policies) {
GetBackendTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&PolicyValueStoreTest::SetCurrentPolicyOnBackendSequence,
base::Unretained(this), base::Passed(policies.DeepCopy())));
content::RunAllBlockingPoolTasksUntilIdle();
}
void SetCurrentPolicyOnBackendSequence(
std::unique_ptr<policy::PolicyMap> policies) {
DCHECK(IsOnBackendSequence());
store_->SetCurrentPolicy(*policies);
}
base::ScopedTempDir scoped_temp_dir_;
content::TestBrowserThreadBundle test_browser_thread_bundle_;
std::unique_ptr<PolicyValueStore> store_;
......@@ -127,7 +142,8 @@ TEST_F(PolicyValueStoreTest, DontProvideRecommendedPolicies) {
policies.Set("may", policy::POLICY_LEVEL_RECOMMENDED,
policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
base::MakeUnique<base::Value>(456), nullptr);
store_->SetCurrentPolicy(policies);
SetCurrentPolicy(policies);
ValueStore::ReadResult result = store_->Get();
ASSERT_TRUE(result->status().ok());
EXPECT_EQ(1u, result->settings().size());
......@@ -169,8 +185,7 @@ TEST_F(PolicyValueStoreTest, NotifyOnChanges) {
policy::PolicyMap policies;
policies.Set("aaa", policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
policy::POLICY_SOURCE_CLOUD, value.CreateDeepCopy(), nullptr);
store_->SetCurrentPolicy(policies);
base::RunLoop().RunUntilIdle();
SetCurrentPolicy(policies);
Mock::VerifyAndClearExpectations(&observer_);
// Notify when new policies are added.
......@@ -185,8 +200,7 @@ TEST_F(PolicyValueStoreTest, NotifyOnChanges) {
policies.Set("bbb", policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
policy::POLICY_SOURCE_CLOUD, value.CreateDeepCopy(), nullptr);
store_->SetCurrentPolicy(policies);
base::RunLoop().RunUntilIdle();
SetCurrentPolicy(policies);
Mock::VerifyAndClearExpectations(&observer_);
// Notify when policies change.
......@@ -204,8 +218,7 @@ TEST_F(PolicyValueStoreTest, NotifyOnChanges) {
policies.Set("bbb", policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
policy::POLICY_SOURCE_CLOUD, new_value.CreateDeepCopy(),
nullptr);
store_->SetCurrentPolicy(policies);
base::RunLoop().RunUntilIdle();
SetCurrentPolicy(policies);
Mock::VerifyAndClearExpectations(&observer_);
// Notify when policies are removed.
......@@ -220,14 +233,12 @@ TEST_F(PolicyValueStoreTest, NotifyOnChanges) {
}
policies.Erase("bbb");
store_->SetCurrentPolicy(policies);
base::RunLoop().RunUntilIdle();
SetCurrentPolicy(policies);
Mock::VerifyAndClearExpectations(&observer_);
// Don't notify when there aren't any changes.
EXPECT_CALL(observer_, OnSettingsChanged(_, _, _)).Times(0);
store_->SetCurrentPolicy(policies);
base::RunLoop().RunUntilIdle();
SetCurrentPolicy(policies);
Mock::VerifyAndClearExpectations(&observer_);
}
......
......@@ -7,11 +7,9 @@
#include "components/sync/model/sync_change_processor.h"
#include "components/sync/model/sync_data.h"
#include "components/sync/protocol/extension_setting_specifics.pb.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/settings_namespace.h"
using content::BrowserThread;
namespace extensions {
SettingsSyncProcessor::SettingsSyncProcessor(
......@@ -22,17 +20,17 @@ SettingsSyncProcessor::SettingsSyncProcessor(
type_(type),
sync_processor_(sync_processor),
initialized_(false) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
CHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
CHECK(sync_processor);
}
SettingsSyncProcessor::~SettingsSyncProcessor() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
}
void SettingsSyncProcessor::Init(const base::DictionaryValue& initial_state) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
CHECK(!initialized_) << "Init called multiple times";
for (base::DictionaryValue::Iterator i(initial_state); !i.IsAtEnd();
......@@ -44,7 +42,7 @@ void SettingsSyncProcessor::Init(const base::DictionaryValue& initial_state) {
syncer::SyncError SettingsSyncProcessor::SendChanges(
const ValueStoreChangeList& changes) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
CHECK(initialized_) << "Init not called";
syncer::SyncChangeList sync_changes;
......@@ -96,7 +94,7 @@ syncer::SyncError SettingsSyncProcessor::SendChanges(
}
void SettingsSyncProcessor::NotifyChanges(const ValueStoreChangeList& changes) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
CHECK(initialized_) << "Init not called";
for (ValueStoreChangeList::const_iterator i = changes.begin();
......
......@@ -10,11 +10,9 @@
#include "components/sync/protocol/app_setting_specifics.pb.h"
#include "components/sync/protocol/extension_setting_specifics.pb.h"
#include "components/sync/protocol/sync.pb.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/storage_frontend.h"
using content::BrowserThread;
namespace extensions {
namespace settings_sync_util {
......@@ -112,7 +110,7 @@ syncer::SyncChange CreateDelete(
syncer::SyncableService* GetSyncableService(content::BrowserContext* context,
syncer::ModelType type) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(type == syncer::APP_SETTINGS || type == syncer::EXTENSION_SETTINGS);
StorageFrontend* frontend = StorageFrontend::Get(context);
SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>(
......
......@@ -12,9 +12,7 @@
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "chrome/browser/extensions/api/storage/syncable_settings_storage.h"
#include "components/sync/model/sync_error_factory.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
#include "extensions/browser/api/storage/backend_task_runner.h"
namespace extensions {
......@@ -59,7 +57,7 @@ SyncStorageBackend::SyncStorageBackend(
observers_(observers),
sync_type_(sync_type),
flare_(flare) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(sync_type_ == syncer::EXTENSION_SETTINGS ||
sync_type_ == syncer::APP_SETTINGS);
}
......@@ -67,14 +65,14 @@ SyncStorageBackend::SyncStorageBackend(
SyncStorageBackend::~SyncStorageBackend() {}
ValueStore* SyncStorageBackend::GetStorage(const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
return GetOrCreateStorageWithSyncData(extension_id, EmptyDictionaryValue());
}
SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData(
const std::string& extension_id,
std::unique_ptr<base::DictionaryValue> sync_data) const {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id);
if (maybe_storage != storage_objs_.end()) {
......@@ -106,7 +104,7 @@ SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData(
}
void SyncStorageBackend::DeleteStorage(const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
// Clear settings when the extension is uninstalled. Leveldb implementations
// will also delete the database from disk when the object is destroyed as a
......@@ -125,7 +123,7 @@ void SyncStorageBackend::DeleteStorage(const std::string& extension_id) {
std::set<std::string> SyncStorageBackend::GetKnownExtensionIDs(
ValueStoreFactory::ModelType model_type) const {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
std::set<std::string> result;
// Storage areas can be in-memory as well as on disk. |storage_objs_| will
......@@ -143,7 +141,7 @@ std::set<std::string> SyncStorageBackend::GetKnownExtensionIDs(
syncer::SyncDataList SyncStorageBackend::GetAllSyncData(syncer::ModelType type)
const {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
// For all extensions, get all their settings. This has the effect
// of bringing in the entire state of extension settings in memory; sad.
syncer::SyncDataList all_sync_data;
......@@ -171,7 +169,7 @@ syncer::SyncMergeResult SyncStorageBackend::MergeDataAndStartSyncing(
const syncer::SyncDataList& initial_sync_data,
std::unique_ptr<syncer::SyncChangeProcessor> sync_processor,
std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK_EQ(sync_type_, type);
DCHECK(!sync_processor_.get());
DCHECK(sync_processor.get());
......@@ -231,7 +229,7 @@ syncer::SyncMergeResult SyncStorageBackend::MergeDataAndStartSyncing(
syncer::SyncError SyncStorageBackend::ProcessSyncChanges(
const tracked_objects::Location& from_here,
const syncer::SyncChangeList& sync_changes) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(sync_processor_.get());
// Group changes by extension, to pass all changes in a single method call.
......@@ -261,7 +259,7 @@ syncer::SyncError SyncStorageBackend::ProcessSyncChanges(
}
void SyncStorageBackend::StopSyncing(syncer::ModelType type) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
DCHECK_EQ(sync_type_, type);
......
......@@ -9,6 +9,7 @@
#include "chrome/browser/extensions/api/storage/sync_storage_backend.h"
#include "chrome/browser/sync/glue/sync_start_util.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/value_store/value_store_factory.h"
#include "extensions/common/api/storage.h"
#include "extensions/common/extension.h"
......@@ -41,19 +42,19 @@ SyncValueStoreCache::SyncValueStoreCache(
// This post is safe since the destructor can only be invoked from the
// same message loop, and any potential post of a deletion task must come
// after the constructor returns.
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::BindOnce(&SyncValueStoreCache::InitOnFileThread,
GetBackendTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&SyncValueStoreCache::InitOnBackend,
base::Unretained(this), factory, observers, profile_path));
}
SyncValueStoreCache::~SyncValueStoreCache() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
}
syncer::SyncableService* SyncValueStoreCache::GetSyncableService(
syncer::ModelType type) const {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(initialized_);
switch (type) {
......@@ -70,7 +71,7 @@ syncer::SyncableService* SyncValueStoreCache::GetSyncableService(
void SyncValueStoreCache::RunWithValueStoreForExtension(
const StorageCallback& callback,
scoped_refptr<const Extension> extension) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(initialized_);
SyncStorageBackend* backend =
extension->is_app() ? app_backend_.get() : extension_backend_.get();
......@@ -78,16 +79,16 @@ void SyncValueStoreCache::RunWithValueStoreForExtension(
}
void SyncValueStoreCache::DeleteStorageSoon(const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
app_backend_->DeleteStorage(extension_id);
extension_backend_->DeleteStorage(extension_id);
}
void SyncValueStoreCache::InitOnFileThread(
void SyncValueStoreCache::InitOnBackend(
const scoped_refptr<ValueStoreFactory>& factory,
const scoped_refptr<SettingsObserverList>& observers,
const base::FilePath& profile_path) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(!initialized_);
app_backend_.reset(new SyncStorageBackend(
factory,
......
......@@ -45,9 +45,9 @@ class SyncValueStoreCache : public ValueStoreCache {
void DeleteStorageSoon(const std::string& extension_id) override;
private:
void InitOnFileThread(const scoped_refptr<ValueStoreFactory>& factory,
const scoped_refptr<SettingsObserverList>& observers,
const base::FilePath& profile_path);
void InitOnBackend(const scoped_refptr<ValueStoreFactory>& factory,
const scoped_refptr<SettingsObserverList>& observers,
const base::FilePath& profile_path);
bool initialized_;
std::unique_ptr<SyncStorageBackend> app_backend_;
......
......@@ -12,11 +12,9 @@
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "components/sync/model/sync_data.h"
#include "components/sync/protocol/extension_setting_specifics.pb.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/settings_namespace.h"
using content::BrowserThread;
namespace extensions {
SyncableSettingsStorage::SyncableSettingsStorage(
......@@ -31,26 +29,26 @@ SyncableSettingsStorage::SyncableSettingsStorage(
delegate_(delegate),
sync_type_(sync_type),
flare_(flare) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
}
SyncableSettingsStorage::~SyncableSettingsStorage() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
}
size_t SyncableSettingsStorage::GetBytesInUse(const std::string& key) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
return delegate_->GetBytesInUse(key);
}
size_t SyncableSettingsStorage::GetBytesInUse(
const std::vector<std::string>& keys) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
return delegate_->GetBytesInUse(keys);
}
size_t SyncableSettingsStorage::GetBytesInUse() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
return delegate_->GetBytesInUse();
}
......@@ -70,24 +68,24 @@ T SyncableSettingsStorage::HandleResult(T result) {
ValueStore::ReadResult SyncableSettingsStorage::Get(
const std::string& key) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
return HandleResult(delegate_->Get(key));
}
ValueStore::ReadResult SyncableSettingsStorage::Get(
const std::vector<std::string>& keys) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
return HandleResult(delegate_->Get(keys));
}
ValueStore::ReadResult SyncableSettingsStorage::Get() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
return HandleResult(delegate_->Get());
}
ValueStore::WriteResult SyncableSettingsStorage::Set(
WriteOptions options, const std::string& key, const base::Value& value) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
WriteResult result = HandleResult(delegate_->Set(options, key, value));
if (!result->status().ok())
return result;
......@@ -97,7 +95,7 @@ ValueStore::WriteResult SyncableSettingsStorage::Set(
ValueStore::WriteResult SyncableSettingsStorage::Set(
WriteOptions options, const base::DictionaryValue& values) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
WriteResult result = HandleResult(delegate_->Set(options, values));
if (!result->status().ok())
return result;
......@@ -107,7 +105,7 @@ ValueStore::WriteResult SyncableSettingsStorage::Set(
ValueStore::WriteResult SyncableSettingsStorage::Remove(
const std::string& key) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
WriteResult result = HandleResult(delegate_->Remove(key));
if (!result->status().ok())
return result;
......@@ -117,7 +115,7 @@ ValueStore::WriteResult SyncableSettingsStorage::Remove(
ValueStore::WriteResult SyncableSettingsStorage::Remove(
const std::vector<std::string>& keys) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
WriteResult result = HandleResult(delegate_->Remove(keys));
if (!result->status().ok())
return result;
......@@ -126,7 +124,7 @@ ValueStore::WriteResult SyncableSettingsStorage::Remove(
}
ValueStore::WriteResult SyncableSettingsStorage::Clear() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
WriteResult result = HandleResult(delegate_->Clear());
if (!result->status().ok())
return result;
......@@ -156,7 +154,7 @@ void SyncableSettingsStorage::SyncResultIfEnabled(
syncer::SyncError SyncableSettingsStorage::StartSyncing(
std::unique_ptr<base::DictionaryValue> sync_state,
std::unique_ptr<SettingsSyncProcessor> sync_processor) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(sync_state);
DCHECK(!sync_processor_.get());
......@@ -182,7 +180,7 @@ syncer::SyncError SyncableSettingsStorage::StartSyncing(
syncer::SyncError SyncableSettingsStorage::SendLocalSettingsToSync(
std::unique_ptr<base::DictionaryValue> local_state) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
if (local_state->empty())
return syncer::SyncError();
......@@ -207,7 +205,7 @@ syncer::SyncError SyncableSettingsStorage::SendLocalSettingsToSync(
syncer::SyncError SyncableSettingsStorage::OverwriteLocalSettingsWithSync(
std::unique_ptr<base::DictionaryValue> sync_state,
std::unique_ptr<base::DictionaryValue> local_state) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
// This is implemented by building up a list of sync changes then sending
// those to ProcessSyncChanges. This generates events like onStorageChanged.
std::unique_ptr<SettingSyncDataList> changes(new SettingSyncDataList());
......@@ -249,13 +247,13 @@ syncer::SyncError SyncableSettingsStorage::OverwriteLocalSettingsWithSync(
}
void SyncableSettingsStorage::StopSyncing() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
sync_processor_.reset();
}
syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges(
std::unique_ptr<SettingSyncDataList> sync_changes) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
DCHECK(!sync_changes->empty()) << "No sync changes for " << extension_id_;
if (!sync_processor_.get()) {
......
......@@ -16,7 +16,6 @@
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
#include "chrome/browser/extensions/api/storage/backend_task_runner.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
......@@ -74,6 +73,7 @@
#include "components/sync_sessions/favicon_cache.h"
#include "components/sync_sessions/sync_sessions_client.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/features/features.h"
#include "ui/base/device_form_factor.h"
......
......@@ -6,11 +6,11 @@
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "chrome/browser/extensions/api/storage/backend_task_runner.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "components/sync/driver/generic_change_processor.h"
#include "components/sync/model/syncable_service.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/extension_system.h"
namespace browser_sync {
......
......@@ -11,11 +11,11 @@
#include "base/logging.h"
#include "base/synchronization/waitable_event.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/storage/backend_task_runner.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/test/integration/extensions_helper.h"
#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
#include "chrome/browser/sync/test/integration/sync_extension_helper.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/storage_frontend.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/value_store/value_store.h"
......
......@@ -9,6 +9,8 @@ assert(enable_extensions,
source_set("storage") {
sources = [
"backend_task_runner.cc",
"backend_task_runner.h",
"local_value_store_cache.cc",
"local_value_store_cache.h",
"settings_namespace.cc",
......
......@@ -2,17 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "content/public/browser/browser_thread.h"
#include "base/task_scheduler/lazy_task_runner.h"
namespace extensions {
// TODO(stanisc): crbug.com/731903: change to LazySequencedTaskRunner once
// migration from BrowserThread::FILE to GetBackendTaskRunner() is complete.
base::LazySequencedTaskRunner g_sequenced_task_task_runner =
LAZY_SEQUENCED_TASK_RUNNER_INITIALIZER({base::MayBlock()});
scoped_refptr<base::SequencedTaskRunner> GetBackendTaskRunner() {
return content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::FILE);
return g_sequenced_task_task_runner.Get();
}
bool IsOnBackendSequence() {
return GetBackendTaskRunner()->RunsTasksInCurrentSequence();
}
} // namespace extensions
......@@ -2,17 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_API_STORAGE_BACKEND_TASK_RUNNER_H_
#define CHROME_BROWSER_EXTENSIONS_API_STORAGE_BACKEND_TASK_RUNNER_H_
#ifndef EXTENSIONS_BROWSER_API_STORAGE_BACKEND_TASK_RUNNER_H_
#define EXTENSIONS_BROWSER_API_STORAGE_BACKEND_TASK_RUNNER_H_
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
namespace extensions {
// Gets the singleton task runner for running SyncStorageBackend on.
// Gets the singleton task runner for running storage backend on.
scoped_refptr<base::SequencedTaskRunner> GetBackendTaskRunner();
// Verifies the the backend task runner above runs tasks in the current
// sequence.
bool IsOnBackendSequence();
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_STORAGE_BACKEND_TASK_RUNNER_H_
#endif // EXTENSIONS_BROWSER_API_STORAGE_BACKEND_TASK_RUNNER_H_
......@@ -9,6 +9,7 @@
#include <limits>
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/weak_unlimited_settings_storage.h"
#include "extensions/browser/value_store/value_store_factory.h"
#include "extensions/common/api/storage.h"
......@@ -39,13 +40,13 @@ LocalValueStoreCache::LocalValueStoreCache(
}
LocalValueStoreCache::~LocalValueStoreCache() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
}
void LocalValueStoreCache::RunWithValueStoreForExtension(
const StorageCallback& callback,
scoped_refptr<const Extension> extension) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
ValueStore* storage = GetStorage(extension.get());
......@@ -61,7 +62,7 @@ void LocalValueStoreCache::RunWithValueStoreForExtension(
}
void LocalValueStoreCache::DeleteStorageSoon(const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(IsOnBackendSequence());
storage_map_.erase(extension_id);
storage_factory_->DeleteSettings(settings_namespace::LOCAL,
ValueStoreFactory::ModelType::APP,
......
......@@ -8,8 +8,8 @@
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/storage/storage_frontend.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system_provider.h"
......@@ -50,7 +50,7 @@ ValueStore* GetStorage(scoped_refptr<const Extension> extension,
ValueStore* storage = NULL;
frontend->RunWithStorage(
extension, settings_namespace, base::Bind(&AssignStorage, &storage));
base::RunLoop().RunUntilIdle();
content::RunAllBlockingPoolTasksUntilIdle();
return storage;
}
......
......@@ -17,6 +17,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/local_value_store_cache.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_registry.h"
......@@ -118,7 +119,7 @@ StorageFrontend::~StorageFrontend() {
for (CacheMap::iterator it = caches_.begin(); it != caches_.end(); ++it) {
ValueStoreCache* cache = it->second;
cache->ShutdownOnUI();
BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, cache);
GetBackendTaskRunner()->DeleteSoon(FROM_HERE, cache);
}
}
......@@ -145,21 +146,18 @@ void StorageFrontend::RunWithStorage(
ValueStoreCache* cache = caches_[settings_namespace];
CHECK(cache);
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&ValueStoreCache::RunWithValueStoreForExtension,
base::Unretained(cache), callback, extension));
GetBackendTaskRunner()->PostTask(
FROM_HERE, base::Bind(&ValueStoreCache::RunWithValueStoreForExtension,
base::Unretained(cache), callback, extension));
}
void StorageFrontend::DeleteStorageSoon(const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (CacheMap::iterator it = caches_.begin(); it != caches_.end(); ++it) {
ValueStoreCache* cache = it->second;
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&ValueStoreCache::DeleteStorageSoon,
base::Unretained(cache),
extension_id));
GetBackendTaskRunner()->PostTask(
FROM_HERE, base::Bind(&ValueStoreCache::DeleteStorageSoon,
base::Unretained(cache), extension_id));
}
}
......@@ -174,7 +172,7 @@ void StorageFrontend::DisableStorageForTesting(
if (it != caches_.end()) {
ValueStoreCache* cache = it->second;
cache->ShutdownOnUI();
BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, cache);
GetBackendTaskRunner()->DeleteSoon(FROM_HERE, cache);
caches_.erase(it);
}
}
......
......@@ -9,11 +9,11 @@
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "content/public/browser/browser_context.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/api/storage/settings_namespace.h"
#include "extensions/browser/api/storage/settings_test_util.h"
......@@ -52,7 +52,7 @@ class ExtensionSettingsFrontendTest : public ExtensionsTest {
void TearDown() override {
frontend_.reset();
// Execute any pending deletion tasks.
base::RunLoop().RunUntilIdle();
content::RunAllBlockingPoolTasksUntilIdle();
ExtensionsTest::TearDown();
}
......@@ -133,7 +133,7 @@ TEST_F(ExtensionSettingsFrontendTest, SettingsClearedOnUninstall) {
// This would be triggered by extension uninstall via a DataDeleter.
frontend_->DeleteStorageSoon(id);
base::RunLoop().RunUntilIdle();
content::RunAllBlockingPoolTasksUntilIdle();
// The storage area may no longer be valid post-uninstall, so re-request.
storage = util::GetStorage(extension, settings::LOCAL, frontend_.get());
......@@ -168,7 +168,7 @@ TEST_F(ExtensionSettingsFrontendTest, LeveldbDatabaseDeletedFromDiskOnClear) {
}
frontend_.reset();
base::RunLoop().RunUntilIdle();
content::RunAllBlockingPoolTasksUntilIdle();
// TODO(kalman): Figure out why this fails, despite appearing to work.
// Leaving this commented out rather than disabling the whole test so that the
// deletion code paths are at least exercised.
......
......@@ -8,6 +8,8 @@
#include "base/json/json_reader.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/iterator.h"
......@@ -50,7 +52,7 @@ ValueStore::StatusCode LevelDbToValueStoreStatusCode(
}
leveldb::Status DeleteValue(leveldb::DB* db, const std::string& key) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
leveldb::WriteBatch batch;
batch.Delete(key);
......@@ -86,13 +88,12 @@ LazyLevelDb::LazyLevelDb(const std::string& uma_client_name,
}
LazyLevelDb::~LazyLevelDb() {
if (db_ && !BrowserThread::CurrentlyOn(BrowserThread::FILE))
BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, db_.release());
base::ThreadRestrictions::AssertIOAllowed();
}
ValueStore::Status LazyLevelDb::Read(const std::string& key,
std::unique_ptr<base::Value>* value) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
DCHECK(value);
std::string value_as_json;
......@@ -118,7 +119,7 @@ ValueStore::Status LazyLevelDb::Read(const std::string& key,
}
ValueStore::Status LazyLevelDb::Delete(const std::string& key) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
ValueStore::Status status = EnsureDbIsOpen();
if (!status.ok())
......@@ -154,7 +155,7 @@ ValueStore::BackingStoreRestoreStatus LazyLevelDb::LogRestoreStatus(
ValueStore::BackingStoreRestoreStatus LazyLevelDb::FixCorruption(
const std::string* key) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
leveldb::Status s;
if (key && db_) {
s = DeleteValue(db_.get(), *key);
......@@ -222,7 +223,7 @@ ValueStore::BackingStoreRestoreStatus LazyLevelDb::FixCorruption(
}
ValueStore::Status LazyLevelDb::EnsureDbIsOpen() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
if (db_)
return ValueStore::Status();
......@@ -268,7 +269,7 @@ ValueStore::Status LazyLevelDb::ToValueStoreError(
}
bool LazyLevelDb::DeleteDbFile() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
db_.reset(); // release any lock on the directory
if (!base::DeleteFile(db_path_, true /* recursive */)) {
LOG(WARNING) << "Failed to delete leveldb database at " << db_path_.value();
......
......@@ -9,12 +9,11 @@
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
#include "content/public/browser/browser_thread.h"
#include "base/threading/thread_restrictions.h"
#include "extensions/browser/value_store/leveldb_value_store.h"
#include "extensions/common/constants.h"
using base::AutoLock;
using content::BrowserThread;
namespace {
......@@ -59,7 +58,7 @@ bool LegacyValueStoreFactory::ModelSettings::DataExists(
std::set<ExtensionId>
LegacyValueStoreFactory::ModelSettings::GetKnownExtensionIDs() const {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
std::set<ExtensionId> result;
// Leveldb databases are directories inside |base_path_|.
......@@ -128,7 +127,7 @@ LegacyValueStoreFactory::SettingsRoot::GetModel(ModelType model_type) {
std::set<ExtensionId>
LegacyValueStoreFactory::SettingsRoot::GetKnownExtensionIDs(
ModelType model_type) const {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
switch (model_type) {
case ValueStoreFactory::ModelType::APP:
DCHECK(apps_ != nullptr);
......@@ -192,8 +191,7 @@ void LegacyValueStoreFactory::DeleteSettings(
settings_namespace::Namespace settings_namespace,
ModelType model_type,
const ExtensionId& extension_id) {
// TODO(cmumford): Verify that we always need to be called on FILE thread.
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
ModelSettings* model_settings =
GetSettingsRoot(settings_namespace).GetModel(model_type);
if (model_settings == nullptr) {
......
......@@ -18,16 +18,15 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/iterator.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
using base::StringPiece;
using content::BrowserThread;
namespace {
......@@ -39,12 +38,14 @@ const char kCannotSerialize[] = "Cannot serialize value to JSON";
LeveldbValueStore::LeveldbValueStore(const std::string& uma_client_name,
const base::FilePath& db_path)
: LazyLevelDb(uma_client_name, db_path) {
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "LeveldbValueStore", base::ThreadTaskRunnerHandle::Get());
base::trace_event::MemoryDumpManager::GetInstance()
->RegisterDumpProviderWithSequencedTaskRunner(
this, "LeveldbValueStore", base::SequencedTaskRunnerHandle::Get(),
base::trace_event::MemoryDumpProvider::Options());
}
LeveldbValueStore::~LeveldbValueStore() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
}
......@@ -74,7 +75,7 @@ ValueStore::ReadResult LeveldbValueStore::Get(const std::string& key) {
ValueStore::ReadResult LeveldbValueStore::Get(
const std::vector<std::string>& keys) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
Status status = EnsureDbIsOpen();
if (!status.ok())
......@@ -95,7 +96,7 @@ ValueStore::ReadResult LeveldbValueStore::Get(
}
ValueStore::ReadResult LeveldbValueStore::Get() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
Status status = EnsureDbIsOpen();
if (!status.ok())
......@@ -129,7 +130,7 @@ ValueStore::ReadResult LeveldbValueStore::Get() {
ValueStore::WriteResult LeveldbValueStore::Set(WriteOptions options,
const std::string& key,
const base::Value& value) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
Status status = EnsureDbIsOpen();
if (!status.ok())
......@@ -149,7 +150,7 @@ ValueStore::WriteResult LeveldbValueStore::Set(WriteOptions options,
ValueStore::WriteResult LeveldbValueStore::Set(
WriteOptions options,
const base::DictionaryValue& settings) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
Status status = EnsureDbIsOpen();
if (!status.ok())
......@@ -172,13 +173,13 @@ ValueStore::WriteResult LeveldbValueStore::Set(
}
ValueStore::WriteResult LeveldbValueStore::Remove(const std::string& key) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
return Remove(std::vector<std::string>(1, key));
}
ValueStore::WriteResult LeveldbValueStore::Remove(
const std::vector<std::string>& keys) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
Status status = EnsureDbIsOpen();
if (!status.ok())
......@@ -208,7 +209,7 @@ ValueStore::WriteResult LeveldbValueStore::Remove(
}
ValueStore::WriteResult LeveldbValueStore::Clear() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
std::unique_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
......@@ -239,7 +240,7 @@ bool LeveldbValueStore::WriteToDbForTest(leveldb::WriteBatch* batch) {
bool LeveldbValueStore::OnMemoryDump(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
// Return true so that the provider is not disabled.
if (!db())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment