diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/components/leveldb | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components/leveldb')
-rw-r--r-- | chromium/components/leveldb/env_mojo.cc | 134 | ||||
-rw-r--r-- | chromium/components/leveldb/env_mojo.h | 18 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_app.cc | 19 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_app.h | 10 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_database_impl.cc | 63 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_database_impl.h | 16 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_mojo_proxy.cc | 9 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_mojo_proxy.h | 12 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_service_impl.cc | 38 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_service_impl.h | 19 | ||||
-rw-r--r-- | chromium/components/leveldb/leveldb_service_unittest.cc | 12 | ||||
-rw-r--r-- | chromium/components/leveldb/public/interfaces/BUILD.gn | 2 | ||||
-rw-r--r-- | chromium/components/leveldb/public/interfaces/leveldb.mojom | 9 | ||||
-rw-r--r-- | chromium/components/leveldb/remote_iterator_unittest.cc | 2 |
14 files changed, 285 insertions, 78 deletions
diff --git a/chromium/components/leveldb/env_mojo.cc b/chromium/components/leveldb/env_mojo.cc index 9b98405d125..0f17d71ec4b 100644 --- a/chromium/components/leveldb/env_mojo.cc +++ b/chromium/components/leveldb/env_mojo.cc @@ -45,6 +45,9 @@ Status FilesystemErrorToStatus(FileError error, char buf[512]; snprintf(buf, sizeof(buf), "%s (MojoFSError: %d::%s)", err_str.c_str(), method, MethodIDToString(method)); + + // TOOD(crbug.com/760362): Map FileError::NOT_FOUND to Status::NotFound, after + // fixing LevelDB to handle the NotFound correctly. return Status::IOError(filename, buf); } @@ -218,6 +221,10 @@ class MojoWritableFile : public leveldb::WritableFile { leveldb::Status SyncParent() { FileError error = thread_->SyncDirectory(dir_, parent_dir_); + if (error != FileError::OK) { + uma_logger_->RecordOSError(leveldb_env::kSyncParent, + static_cast<base::File::Error>(error)); + } return error == FileError::OK ? Status::OK() : Status::IOError(filename_, @@ -257,6 +264,58 @@ class Thread : public base::PlatformThread::Delegate { DISALLOW_COPY_AND_ASSIGN(Thread); }; +class Retrier { + public: + Retrier(leveldb_env::MethodID method, MojoRetrierProvider* provider) + : start_(base::TimeTicks::Now()), + limit_(start_ + base::TimeDelta::FromMilliseconds( + provider->MaxRetryTimeMillis())), + last_(start_), + time_to_sleep_(base::TimeDelta::FromMilliseconds(10)), + success_(true), + method_(method), + last_error_(base::File::FILE_OK), + provider_(provider) {} + + ~Retrier() { + if (success_) { + provider_->RecordRetryTime(method_, last_ - start_); + if (last_error_ != base::File::FILE_OK) { + DCHECK_LT(last_error_, 0); + provider_->RecordRecoveredFromError(method_, last_error_); + } + } + } + + bool ShouldKeepTrying(FileError error) { + return ShouldKeepTrying(static_cast<base::File::Error>(error)); + } + + bool ShouldKeepTrying(base::File::Error last_error) { + DCHECK_NE(last_error, base::File::FILE_OK); + last_error_ = last_error; + if (last_ < limit_) { + base::PlatformThread::Sleep(time_to_sleep_); + last_ = base::TimeTicks::Now(); + return true; + } + success_ = false; + return false; + } + + private: + base::TimeTicks start_; + base::TimeTicks limit_; + base::TimeTicks last_; + base::TimeDelta time_to_sleep_; + bool success_; + leveldb_env::MethodID method_; + base::File::Error last_error_; + MojoRetrierProvider* provider_; + + DISALLOW_COPY_AND_ASSIGN(Retrier); +}; + } // namespace MojoEnv::MojoEnv(scoped_refptr<LevelDBMojoProxy> file_thread, @@ -358,7 +417,11 @@ Status MojoEnv::DeleteFile(const std::string& fname) { Status MojoEnv::CreateDir(const std::string& dirname) { TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname); - FileError error = thread_->CreateDir(dir_, dirname); + Retrier retrier(leveldb_env::kCreateDir, this); + FileError error; + do { + error = thread_->CreateDir(dir_, dirname); + } while (error != FileError::OK && retrier.ShouldKeepTrying(error)); if (error != FileError::OK) RecordFileError(leveldb_env::kCreateDir, error); return FilesystemErrorToStatus(error, dirname, leveldb_env::kCreateDir); @@ -383,7 +446,13 @@ Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) { Status MojoEnv::RenameFile(const std::string& src, const std::string& target) { TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target); - FileError error = thread_->RenameFile(dir_, src, target); + if (!thread_->FileExists(dir_, src)) + return Status::OK(); + Retrier retrier(leveldb_env::kRenameFile, this); + FileError error; + do { + error = thread_->RenameFile(dir_, src, target); + } while (error != FileError::OK && retrier.ShouldKeepTrying(error)); if (error != FileError::OK) RecordFileError(leveldb_env::kRenameFile, error); return FilesystemErrorToStatus(error, src, leveldb_env::kRenameFile); @@ -392,8 +461,11 @@ Status MojoEnv::RenameFile(const std::string& src, const std::string& target) { Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) { TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname); - std::pair<FileError, LevelDBMojoProxy::OpaqueLock*> p = - thread_->LockFile(dir_, fname); + Retrier retrier(leveldb_env::kLockFile, this); + std::pair<FileError, LevelDBMojoProxy::OpaqueLock*> p; + do { + p = thread_->LockFile(dir_, fname); + } while (p.first != FileError::OK && retrier.ShouldKeepTrying(p.first)); if (p.first != FileError::OK) RecordFileError(leveldb_env::kLockFile, p.first); @@ -443,6 +515,26 @@ Status MojoEnv::NewLogger(const std::string& fname, Logger** result) { } } +uint64_t MojoEnv::NowMicros() { + return base::TimeTicks::Now().ToInternalValue(); +} + +void MojoEnv::SleepForMicroseconds(int micros) { + // Round up to the next millisecond. + base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros)); +} + +void MojoEnv::Schedule(void (*function)(void* arg), void* arg) { + base::PostTaskWithTraits(FROM_HERE, + {base::MayBlock(), base::WithBaseSyncPrimitives(), + base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, + base::Bind(function, arg)); +} + +void MojoEnv::StartThread(void (*function)(void* arg), void* arg) { + new Thread(function, arg); // Will self-delete. +} + void MojoEnv::RecordErrorAt(leveldb_env::MethodID method) const { UMA_HISTOGRAM_ENUMERATION("MojoLevelDBEnv.IOError", method, leveldb_env::kNumEntries); @@ -464,29 +556,29 @@ void MojoEnv::RecordBytesWritten(int amount) const { UMA_HISTOGRAM_COUNTS_10M("Storage.BytesWritten.MojoLevelDBEnv", amount); } -void MojoEnv::RecordFileError(leveldb_env::MethodID method, - FileError error) const { - RecordOSError(method, static_cast<base::File::Error>(error)); -} - -uint64_t MojoEnv::NowMicros() { - return base::TimeTicks::Now().ToInternalValue(); +int MojoEnv::MaxRetryTimeMillis() const { + return 1000; } -void MojoEnv::SleepForMicroseconds(int micros) { - // Round up to the next millisecond. - base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros)); +void MojoEnv::RecordRetryTime(leveldb_env::MethodID method, + base::TimeDelta time) const { + std::string uma_name = std::string("MojoLevelDBEnv.TimeUntilSuccessFor") + + MethodIDToString(method); + UmaHistogramCustomTimes(uma_name, time, base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMilliseconds(1001), 42); } -void MojoEnv::Schedule(void (*function)(void* arg), void* arg) { - base::PostTaskWithTraits(FROM_HERE, - {base::MayBlock(), base::WithBaseSyncPrimitives(), - base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, - base::Bind(function, arg)); +void MojoEnv::RecordRecoveredFromError(leveldb_env::MethodID method, + base::File::Error error) const { + std::string uma_name = + std::string("MojoLevelDBEnv.RetryRecoveredFromErrorIn") + + MethodIDToString(method); + base::UmaHistogramExactLinear(uma_name, -error, -base::File::FILE_ERROR_MAX); } -void MojoEnv::StartThread(void (*function)(void* arg), void* arg) { - new Thread(function, arg); // Will self-delete. +void MojoEnv::RecordFileError(leveldb_env::MethodID method, + FileError error) const { + RecordOSError(method, static_cast<base::File::Error>(error)); } } // namespace leveldb diff --git a/chromium/components/leveldb/env_mojo.h b/chromium/components/leveldb/env_mojo.h index ca0f683902e..db240462131 100644 --- a/chromium/components/leveldb/env_mojo.h +++ b/chromium/components/leveldb/env_mojo.h @@ -12,12 +12,23 @@ namespace leveldb { +class MojoRetrierProvider { + public: + virtual int MaxRetryTimeMillis() const = 0; + virtual void RecordRetryTime(leveldb_env::MethodID method, + base::TimeDelta time) const = 0; + virtual void RecordRecoveredFromError(leveldb_env::MethodID method, + base::File::Error error) const = 0; +}; + // An implementation of the leveldb operating system interaction code which // proxies to a specified mojo:filesystem directory. Most of these methods are // synchronous and block on responses from the filesystem service. That's fine // since, for the most part, they merely open files or check for a file's // existence. -class MojoEnv : public Env, public leveldb_env::UMALogger { +class MojoEnv : public Env, + public leveldb_env::UMALogger, + public MojoRetrierProvider { public: MojoEnv(scoped_refptr<LevelDBMojoProxy> file_thread, LevelDBMojoProxy::OpaqueDir* dir); @@ -56,6 +67,11 @@ class MojoEnv : public Env, public leveldb_env::UMALogger { base::File::Error error) const override; void RecordBytesRead(int amount) const override; void RecordBytesWritten(int amount) const override; + int MaxRetryTimeMillis() const override; + void RecordRetryTime(leveldb_env::MethodID method, + base::TimeDelta time) const override; + void RecordRecoveredFromError(leveldb_env::MethodID method, + base::File::Error error) const override; void RecordFileError(leveldb_env::MethodID method, filesystem::mojom::FileError error) const; diff --git a/chromium/components/leveldb/leveldb_app.cc b/chromium/components/leveldb/leveldb_app.cc index cd5447ea05e..76b48b38b19 100644 --- a/chromium/components/leveldb/leveldb_app.cc +++ b/chromium/components/leveldb/leveldb_app.cc @@ -4,12 +4,15 @@ #include "components/leveldb/leveldb_app.h" +#include "base/task_scheduler/post_task.h" #include "components/leveldb/leveldb_service_impl.h" #include "services/service_manager/public/cpp/service_context.h" namespace leveldb { -LevelDBApp::LevelDBApp() : file_thread_("LevelDBFile") { +LevelDBApp::LevelDBApp() + : file_task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN})) { registry_.AddInterface<mojom::LevelDBService>( base::Bind(&LevelDBApp::Create, base::Unretained(this))); } @@ -22,18 +25,12 @@ void LevelDBApp::OnBindInterface( const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) { - registry_.BindInterface(source_info, interface_name, - std::move(interface_pipe)); + registry_.BindInterface(interface_name, std::move(interface_pipe)); } -void LevelDBApp::Create(const service_manager::BindSourceInfo& source_info, - leveldb::mojom::LevelDBServiceRequest request) { - if (!service_) { - if (!file_thread_.IsRunning()) - file_thread_.Start(); - service_.reset( - new LevelDBServiceImpl(file_thread_.message_loop()->task_runner())); - } +void LevelDBApp::Create(leveldb::mojom::LevelDBServiceRequest request) { + if (!service_) + service_.reset(new LevelDBServiceImpl(file_task_runner_)); bindings_.AddBinding(service_.get(), std::move(request)); } diff --git a/chromium/components/leveldb/leveldb_app.h b/chromium/components/leveldb/leveldb_app.h index 78d542b3437..f5696a31d6b 100644 --- a/chromium/components/leveldb/leveldb_app.h +++ b/chromium/components/leveldb/leveldb_app.h @@ -7,12 +7,15 @@ #include <memory> -#include "base/threading/thread.h" #include "components/leveldb/public/interfaces/leveldb.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +namespace base { +class SequencedTaskRunner; +} + namespace leveldb { class LevelDBApp : public service_manager::Service { @@ -27,14 +30,13 @@ class LevelDBApp : public service_manager::Service { const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; - void Create(const service_manager::BindSourceInfo& source_info, - leveldb::mojom::LevelDBServiceRequest request); + void Create(leveldb::mojom::LevelDBServiceRequest request); std::unique_ptr<mojom::LevelDBService> service_; service_manager::BinderRegistry registry_; mojo::BindingSet<mojom::LevelDBService> bindings_; - base::Thread file_thread_; + scoped_refptr<base::SequencedTaskRunner> file_task_runner_; DISALLOW_COPY_AND_ASSIGN(LevelDBApp); }; diff --git a/chromium/components/leveldb/leveldb_database_impl.cc b/chromium/components/leveldb/leveldb_database_impl.cc index 59ab0787066..f0f509a28c6 100644 --- a/chromium/components/leveldb/leveldb_database_impl.cc +++ b/chromium/components/leveldb/leveldb_database_impl.cc @@ -4,14 +4,19 @@ #include "components/leveldb/leveldb_database_impl.h" +#include <inttypes.h> #include <map> #include <string> #include <utility> #include "base/optional.h" #include "base/rand_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" +#include "base/trace_event/memory_dump_manager.h" #include "components/leveldb/env_mojo.h" #include "components/leveldb/public/cpp/util.h" +#include "third_party/leveldatabase/env_chromium.h" #include "third_party/leveldatabase/src/include/leveldb/db.h" #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" @@ -37,10 +42,22 @@ leveldb::Status ForEachWithPrefix(leveldb::DB* db, LevelDBDatabaseImpl::LevelDBDatabaseImpl( std::unique_ptr<leveldb::Env> environment, - std::unique_ptr<leveldb::DB> db) - : environment_(std::move(environment)), db_(std::move(db)) {} + std::unique_ptr<leveldb::DB> db, + std::unique_ptr<leveldb::Cache> cache, + base::Optional<base::trace_event::MemoryAllocatorDumpGuid> memory_dump_id) + : environment_(std::move(environment)), + cache_(std::move(cache)), + db_(std::move(db)), + memory_dump_id_(memory_dump_id) { + base::trace_event::MemoryDumpManager::GetInstance() + ->RegisterDumpProviderWithSequencedTaskRunner( + this, "MojoLevelDB", base::SequencedTaskRunnerHandle::Get(), + MemoryDumpProvider::Options()); +} LevelDBDatabaseImpl::~LevelDBDatabaseImpl() { + base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( + this); for (auto& p : iterator_map_) delete p.second; for (auto& p : snapshot_map_) @@ -270,6 +287,48 @@ void LevelDBDatabaseImpl::IteratorPrev(const base::UnguessableToken& iterator, ReplyToIteratorMessage(it->second, std::move(callback)); } +bool LevelDBDatabaseImpl::OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { + std::string name = base::StringPrintf("leveldb/mojo/0x%" PRIXPTR, + reinterpret_cast<uintptr_t>(db_.get())); + auto* mad = pmd->CreateAllocatorDump(name); + + uint64_t memory_usage = 0; + std::string memory_usage_string; + bool got_memory_usage = + db_->GetProperty("leveldb.approximate-memory-usage", + &memory_usage_string) && + base::StringToUint64(memory_usage_string, &memory_usage); + DCHECK(got_memory_usage); + mad->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + memory_usage); + if (cache_) { + auto* cache_mad = pmd->CreateAllocatorDump(name + "/block_cache"); + cache_mad->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + cache_->TotalCharge()); + } + + // All leveldb databases are already dumped by leveldb_env::DBTracker. Add + // an edge to avoid double counting. + pmd->AddSuballocation(mad->guid(), + leveldb_env::DBTracker::GetMemoryDumpName(db_.get())); + + if (memory_dump_id_) { + auto* global_dump = pmd->CreateSharedGlobalAllocatorDump(*memory_dump_id_); + pmd->AddOwnershipEdge(global_dump->guid(), mad->guid()); + // Add size to global dump to propagate the size of the database to the + // client's dump. + global_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + memory_usage); + } + + return true; +} + void LevelDBDatabaseImpl::ReplyToIteratorMessage( leveldb::Iterator* it, IteratorSeekToFirstCallback callback) { diff --git a/chromium/components/leveldb/leveldb_database_impl.h b/chromium/components/leveldb/leveldb_database_impl.h index 277748d49ef..31c9cbabb05 100644 --- a/chromium/components/leveldb/leveldb_database_impl.h +++ b/chromium/components/leveldb/leveldb_database_impl.h @@ -7,18 +7,24 @@ #include <memory> +#include "base/trace_event/memory_dump_provider.h" #include "base/unguessable_token.h" #include "components/leveldb/public/interfaces/leveldb.mojom.h" #include "mojo/public/cpp/bindings/interface_request.h" +#include "third_party/leveldatabase/src/include/leveldb/cache.h" #include "third_party/leveldatabase/src/include/leveldb/db.h" namespace leveldb { // The backing to a database object that we pass to our called. -class LevelDBDatabaseImpl : public mojom::LevelDBDatabase { +class LevelDBDatabaseImpl : public mojom::LevelDBDatabase, + public base::trace_event::MemoryDumpProvider { public: LevelDBDatabaseImpl(std::unique_ptr<leveldb::Env> environment, - std::unique_ptr<leveldb::DB> db); + std::unique_ptr<leveldb::DB> db, + std::unique_ptr<leveldb::Cache> cache, + base::Optional<base::trace_event::MemoryAllocatorDumpGuid> + memory_dump_id); ~LevelDBDatabaseImpl() override; // Overridden from LevelDBDatabase: @@ -56,6 +62,10 @@ class LevelDBDatabaseImpl : public mojom::LevelDBDatabase { void IteratorPrev(const base::UnguessableToken& iterator, IteratorPrevCallback callback) override; + // base::trace_event::MemoryDumpProvider implementation. + bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) override; + private: // Returns the state of |it| to a caller. Note: This assumes that all the // iterator movement methods have the same callback signature. We don't @@ -67,7 +77,9 @@ class LevelDBDatabaseImpl : public mojom::LevelDBDatabase { leveldb::WriteBatch* batch); std::unique_ptr<leveldb::Env> environment_; + std::unique_ptr<leveldb::Cache> cache_; std::unique_ptr<leveldb::DB> db_; + base::Optional<base::trace_event::MemoryAllocatorDumpGuid> memory_dump_id_; std::map<base::UnguessableToken, const Snapshot*> snapshot_map_; diff --git a/chromium/components/leveldb/leveldb_mojo_proxy.cc b/chromium/components/leveldb/leveldb_mojo_proxy.cc index 523859c3762..5c78d33d317 100644 --- a/chromium/components/leveldb/leveldb_mojo_proxy.cc +++ b/chromium/components/leveldb/leveldb_mojo_proxy.cc @@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/single_thread_task_runner.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/bindings/sync_call_restrictions.h" @@ -28,9 +27,9 @@ struct LevelDBMojoProxy::OpaqueDir { }; LevelDBMojoProxy::LevelDBMojoProxy( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) + scoped_refptr<base::SequencedTaskRunner> task_runner) : task_runner_(std::move(task_runner)), outstanding_opaque_dirs_(0) { - DCHECK(!task_runner_->BelongsToCurrentThread()); + DCHECK(!task_runner_->RunsTasksInCurrentSequence()); } LevelDBMojoProxy::OpaqueDir* LevelDBMojoProxy::RegisterDirectory( @@ -144,7 +143,7 @@ LevelDBMojoProxy::~LevelDBMojoProxy() { } void LevelDBMojoProxy::RunInternal(const base::Closure& task) { - if (task_runner_->BelongsToCurrentThread()) { + if (task_runner_->RunsTasksInCurrentSequence()) { task.Run(); } else { base::WaitableEvent done_event( @@ -291,7 +290,7 @@ void LevelDBMojoProxy::RenameFileImpl(OpaqueDir* dir, const std::string& new_path, filesystem::mojom::FileError* out_error) { mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync; - bool completed = dir->directory->Rename(old_path, new_path, out_error); + bool completed = dir->directory->Replace(old_path, new_path, out_error); DCHECK(completed); } diff --git a/chromium/components/leveldb/leveldb_mojo_proxy.h b/chromium/components/leveldb/leveldb_mojo_proxy.h index 2eef1a41d1d..4b5e0ad6908 100644 --- a/chromium/components/leveldb/leveldb_mojo_proxy.h +++ b/chromium/components/leveldb/leveldb_mojo_proxy.h @@ -14,13 +14,11 @@ #include "base/callback_forward.h" #include "base/files/file.h" #include "base/memory/ref_counted.h" +#include "base/sequenced_task_runner.h" + #include "base/synchronization/waitable_event.h" #include "components/filesystem/public/interfaces/directory.mojom.h" -namespace base { -class SingleThreadTaskRunner; -} - namespace leveldb { // A proxy for thread safe access to Mojo objects from multiple threads. @@ -35,7 +33,7 @@ namespace leveldb { class LevelDBMojoProxy : public base::RefCountedThreadSafe<LevelDBMojoProxy> { public: explicit LevelDBMojoProxy( - scoped_refptr<base::SingleThreadTaskRunner> task_runner); + scoped_refptr<base::SequencedTaskRunner> task_runner); // A private struct to hide the underlying file that holds the lock from our // callers, forcing them to go through our LockFile()/UnlockFile() interface @@ -152,9 +150,9 @@ class LevelDBMojoProxy : public base::RefCountedThreadSafe<LevelDBMojoProxy> { void UnlockFileImpl(std::unique_ptr<OpaqueLock> lock, filesystem::mojom::FileError* out_error); - // The task runner which represents the thread that all mojo objects are + // The task runner which represents the sequence that all mojo objects are // bound to. - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; int outstanding_opaque_dirs_; diff --git a/chromium/components/leveldb/leveldb_service_impl.cc b/chromium/components/leveldb/leveldb_service_impl.cc index f2e4eb8597d..a6406166403 100644 --- a/chromium/components/leveldb/leveldb_service_impl.cc +++ b/chromium/components/leveldb/leveldb_service_impl.cc @@ -22,7 +22,7 @@ namespace leveldb { LevelDBServiceImpl::LevelDBServiceImpl( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) + scoped_refptr<base::SequencedTaskRunner> file_task_runner) : thread_(new LevelDBMojoProxy(std::move(file_task_runner))) {} LevelDBServiceImpl::~LevelDBServiceImpl() {} @@ -30,16 +30,21 @@ LevelDBServiceImpl::~LevelDBServiceImpl() {} void LevelDBServiceImpl::Open( filesystem::mojom::DirectoryPtr directory, const std::string& dbname, + const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>& + memory_dump_id, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, OpenCallback callback) { OpenWithOptions(leveldb::mojom::OpenOptions::New(), std::move(directory), - dbname, std::move(database), std::move(callback)); + dbname, memory_dump_id, std::move(database), + std::move(callback)); } void LevelDBServiceImpl::OpenWithOptions( leveldb::mojom::OpenOptionsPtr open_options, filesystem::mojom::DirectoryPtr directory, const std::string& dbname, + const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>& + memory_dump_id, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, OpenCallback callback) { leveldb::Options options; @@ -59,20 +64,26 @@ void LevelDBServiceImpl::OpenWithOptions( std::unique_ptr<MojoEnv> env_mojo(new MojoEnv(thread_, dir)); options.env = env_mojo.get(); - leveldb::DB* db = nullptr; - leveldb::Status s = leveldb::DB::Open(options, dbname, &db); + std::unique_ptr<leveldb::Cache> cache( + leveldb::NewLRUCache(open_options->block_cache_size)); + options.block_cache = cache.get(); + + std::unique_ptr<leveldb::DB> db; + leveldb::Status s = leveldb_env::OpenDB(options, dbname, &db); if (s.ok()) { - mojo::MakeStrongAssociatedBinding( - base::MakeUnique<LevelDBDatabaseImpl>(std::move(env_mojo), - base::WrapUnique(db)), - std::move(database)); + mojo::MakeStrongAssociatedBinding(base::MakeUnique<LevelDBDatabaseImpl>( + std::move(env_mojo), std::move(db), + std::move(cache), memory_dump_id), + std::move(database)); } std::move(callback).Run(LeveldbStatusToError(s)); } void LevelDBServiceImpl::OpenInMemory( + const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>& + memory_dump_id, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, OpenCallback callback) { leveldb::Options options; @@ -83,13 +94,14 @@ void LevelDBServiceImpl::OpenInMemory( leveldb::NewMemEnv(leveldb::Env::Default())); options.env = env.get(); - leveldb::DB* db = nullptr; - leveldb::Status s = leveldb::DB::Open(options, "", &db); + std::unique_ptr<leveldb::DB> db; + leveldb::Status s = leveldb_env::OpenDB(options, "", &db); if (s.ok()) { - mojo::MakeStrongAssociatedBinding(base::MakeUnique<LevelDBDatabaseImpl>( - std::move(env), base::WrapUnique(db)), - std::move(database)); + mojo::MakeStrongAssociatedBinding( + base::MakeUnique<LevelDBDatabaseImpl>(std::move(env), std::move(db), + nullptr, memory_dump_id), + std::move(database)); } std::move(callback).Run(LeveldbStatusToError(s)); diff --git a/chromium/components/leveldb/leveldb_service_impl.h b/chromium/components/leveldb/leveldb_service_impl.h index 9a5beed6d99..1d5fab0b3d3 100644 --- a/chromium/components/leveldb/leveldb_service_impl.h +++ b/chromium/components/leveldb/leveldb_service_impl.h @@ -6,11 +6,14 @@ #define COMPONENTS_LEVELDB_LEVELDB_SERVICE_IMPL_H_ #include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" #include "components/leveldb/leveldb_mojo_proxy.h" #include "components/leveldb/public/interfaces/leveldb.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" +namespace base { +class SequencedTaskRunner; +} + namespace leveldb { // Creates LevelDBDatabases based scoped to a |directory|/|dbname|. @@ -19,23 +22,29 @@ class LevelDBServiceImpl : public mojom::LevelDBService { // The |file_task_runner| is used to run tasks to interact with the // file_service. Specifically this task runner must NOT be the same as the // task runner this implementation runs on, or deadlock might occur. - LevelDBServiceImpl( - scoped_refptr<base::SingleThreadTaskRunner> file_task_runner); + LevelDBServiceImpl(scoped_refptr<base::SequencedTaskRunner> file_task_runner); ~LevelDBServiceImpl() override; // Overridden from LevelDBService: void Open(filesystem::mojom::DirectoryPtr directory, const std::string& dbname, + const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>& + memory_dump_id, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, OpenCallback callback) override; void OpenWithOptions( leveldb::mojom::OpenOptionsPtr open_options, filesystem::mojom::DirectoryPtr directory, const std::string& dbname, + const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>& + memory_dump_id, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, OpenCallback callback) override; - void OpenInMemory(leveldb::mojom::LevelDBDatabaseAssociatedRequest database, - OpenInMemoryCallback callback) override; + void OpenInMemory( + const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>& + memory_dump_id, + leveldb::mojom::LevelDBDatabaseAssociatedRequest database, + OpenInMemoryCallback callback) override; void Destroy(filesystem::mojom::DirectoryPtr directory, const std::string& dbname, DestroyCallback callback) override; diff --git a/chromium/components/leveldb/leveldb_service_unittest.cc b/chromium/components/leveldb/leveldb_service_unittest.cc index 0651b07a56f..0ffefeb7e9a 100644 --- a/chromium/components/leveldb/leveldb_service_unittest.cc +++ b/chromium/components/leveldb/leveldb_service_unittest.cc @@ -98,7 +98,7 @@ void LevelDBSyncOpenInMemory(mojom::LevelDBService* leveldb, mojom::LevelDBDatabaseAssociatedRequest database, mojom::DatabaseError* out_error) { base::RunLoop run_loop; - leveldb->OpenInMemory(std::move(database), + leveldb->OpenInMemory(base::nullopt, std::move(database), Capture(out_error, run_loop.QuitClosure())); run_loop.Run(); } @@ -265,7 +265,7 @@ TEST_F(LevelDBServiceTest, Reconnect) { options->create_if_missing = true; base::RunLoop run_loop; leveldb()->OpenWithOptions(std::move(options), std::move(directory), "test", - MakeRequest(&database), + base::nullopt, MakeRequest(&database), Capture(&error, run_loop.QuitClosure())); run_loop.Run(); EXPECT_EQ(mojom::DatabaseError::OK, error); @@ -285,7 +285,8 @@ TEST_F(LevelDBServiceTest, Reconnect) { // Reconnect to the database. mojom::LevelDBDatabaseAssociatedPtr database; base::RunLoop run_loop; - leveldb()->Open(std::move(directory), "test", MakeRequest(&database), + leveldb()->Open(std::move(directory), "test", base::nullopt, + MakeRequest(&database), Capture(&error, run_loop.QuitClosure())); run_loop.Run(); EXPECT_EQ(mojom::DatabaseError::OK, error); @@ -315,7 +316,7 @@ TEST_F(LevelDBServiceTest, Destroy) { options->create_if_missing = true; base::RunLoop run_loop; leveldb()->OpenWithOptions(std::move(options), std::move(directory), "test", - MakeRequest(&database), + base::nullopt, MakeRequest(&database), Capture(&error, run_loop.QuitClosure())); run_loop.Run(); EXPECT_EQ(mojom::DatabaseError::OK, error); @@ -347,7 +348,8 @@ TEST_F(LevelDBServiceTest, Destroy) { // Reconnect to the database should fail. mojom::LevelDBDatabaseAssociatedPtr database; base::RunLoop run_loop; - leveldb()->Open(std::move(directory), "test", MakeRequest(&database), + leveldb()->Open(std::move(directory), "test", base::nullopt, + MakeRequest(&database), Capture(&error, run_loop.QuitClosure())); run_loop.Run(); EXPECT_EQ(mojom::DatabaseError::INVALID_ARGUMENT, error); diff --git a/chromium/components/leveldb/public/interfaces/BUILD.gn b/chromium/components/leveldb/public/interfaces/BUILD.gn index 514eeb9f785..1b3172e6408 100644 --- a/chromium/components/leveldb/public/interfaces/BUILD.gn +++ b/chromium/components/leveldb/public/interfaces/BUILD.gn @@ -5,6 +5,8 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("interfaces") { + support_lazy_serialization = true + sources = [ "leveldb.mojom", ] diff --git a/chromium/components/leveldb/public/interfaces/leveldb.mojom b/chromium/components/leveldb/public/interfaces/leveldb.mojom index 11e56709553..938bd730d4a 100644 --- a/chromium/components/leveldb/public/interfaces/leveldb.mojom +++ b/chromium/components/leveldb/public/interfaces/leveldb.mojom @@ -6,6 +6,7 @@ module leveldb.mojom; import "components/filesystem/public/interfaces/directory.mojom"; import "mojo/common/unguessable_token.mojom"; +import "mojo/common/memory_allocator_dump_cross_process_uid.mojom"; enum DatabaseError { OK, @@ -58,6 +59,9 @@ struct OpenOptions { // https://code.google.com/p/chromium/issues/detail?id=227313#c11 for // details.) int32 max_open_files = 80; + + // Default size is 8 megabytes. + uint64 block_cache_size = 8388608; }; // Service which hands out databases. @@ -66,16 +70,19 @@ interface LevelDBService { // Fails if the database doesn't already exist. Open(filesystem.mojom.Directory directory, string dbname, + mojo.common.mojom.MemoryAllocatorDumpCrossProcessUid? memory_dump_id, associated LevelDBDatabase& database) => (DatabaseError status); // Open the database with the specified "name" in the specified "directory". OpenWithOptions(OpenOptions options, filesystem.mojom.Directory directory, string dbname, + mojo.common.mojom.MemoryAllocatorDumpCrossProcessUid? memory_dump_id, associated LevelDBDatabase& database) => (DatabaseError status); // Opens a database stored purely in memory. - OpenInMemory(associated LevelDBDatabase& database) => (DatabaseError status); + OpenInMemory(mojo.common.mojom.MemoryAllocatorDumpCrossProcessUid? memory_dump_id, + associated LevelDBDatabase& database) => (DatabaseError status); // Destroys the contents of the specified database. Returns OK if the database // already didn't exist. diff --git a/chromium/components/leveldb/remote_iterator_unittest.cc b/chromium/components/leveldb/remote_iterator_unittest.cc index 8665711ae65..f37bd48d1a1 100644 --- a/chromium/components/leveldb/remote_iterator_unittest.cc +++ b/chromium/components/leveldb/remote_iterator_unittest.cc @@ -52,7 +52,7 @@ class RemoteIteratorTest : public service_manager::test::ServiceTest { mojom::DatabaseError error; base::RunLoop run_loop; - leveldb()->OpenInMemory(MakeRequest(&database_), + leveldb()->OpenInMemory(base::nullopt, MakeRequest(&database_), Capture(&error, run_loop.QuitClosure())); run_loop.Run(); EXPECT_EQ(mojom::DatabaseError::OK, error); |