Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/leveldb/env_mojo.h" | 5 #include "components/leveldb/env_mojo.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "base/lazy_instance.h" | |
| 12 #include "base/strings/string_number_conversions.h" | |
| 11 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "base/strings/stringprintf.h" | |
| 12 #include "base/trace_event/trace_event.h" | 15 #include "base/trace_event/trace_event.h" |
| 13 #include "third_party/leveldatabase/chromium_logger.h" | 16 #include "third_party/leveldatabase/chromium_logger.h" |
| 14 #include "third_party/leveldatabase/src/include/leveldb/status.h" | 17 #include "third_party/leveldatabase/src/include/leveldb/status.h" |
| 15 | 18 |
| 16 namespace leveldb { | 19 namespace leveldb { |
| 17 | 20 |
| 18 namespace { | 21 namespace { |
| 19 | 22 |
| 20 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb"); | 23 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb"); |
| 21 | 24 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 std::string filename_; | 211 std::string filename_; |
| 209 base::File file_; | 212 base::File file_; |
| 210 Type file_type_; | 213 Type file_type_; |
| 211 LevelDBMojoProxy::OpaqueDir* dir_; | 214 LevelDBMojoProxy::OpaqueDir* dir_; |
| 212 std::string parent_dir_; | 215 std::string parent_dir_; |
| 213 scoped_refptr<LevelDBMojoProxy> thread_; | 216 scoped_refptr<LevelDBMojoProxy> thread_; |
| 214 | 217 |
| 215 DISALLOW_COPY_AND_ASSIGN(MojoWritableFile); | 218 DISALLOW_COPY_AND_ASSIGN(MojoWritableFile); |
| 216 }; | 219 }; |
| 217 | 220 |
| 221 base::LazyInstance<std::vector<MojoEnv*>>::Leaky g_mojo_envs = | |
| 222 LAZY_INSTANCE_INITIALIZER; | |
| 223 | |
| 218 } // namespace | 224 } // namespace |
| 219 | 225 |
| 220 MojoEnv::MojoEnv(const std::string& name, | 226 // static |
| 221 scoped_refptr<LevelDBMojoProxy> file_thread, | 227 MojoEnv* MojoEnv::Get( |
| 222 LevelDBMojoProxy::OpaqueDir* dir) | 228 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { |
| 223 : ChromiumEnv(name), thread_(file_thread), dir_(dir) {} | 229 auto* envs = g_mojo_envs.Pointer(); |
| 230 for (MojoEnv* env : *envs) { | |
| 231 if (env->thread_->task_runner() == file_task_runner) | |
|
michaeln
2017/03/27 20:24:10
I think this does ptr comparison, do we seen multi
Marijn Kruisselbrink
2017/03/31 23:26:24
Part of the confusion/complication is because of h
| |
| 232 return env; | |
| 233 } | |
| 234 MojoEnv* env = new MojoEnv(std::move(file_task_runner)); | |
| 235 envs->push_back(env); | |
| 236 return env; | |
| 237 } | |
| 224 | 238 |
| 225 MojoEnv::~MojoEnv() { | 239 std::string MojoEnv::RegisterDirectory( |
|
michaeln
2017/03/27 20:24:10
This function/class is not thread safe (dirs_), do
| |
| 226 thread_->UnregisterDirectory(dir_); | 240 filesystem::mojom::DirectoryPtr directory) { |
| 241 LevelDBMojoProxy::OpaqueDir* dir = | |
| 242 thread_->RegisterDirectory(std::move(directory)); | |
| 243 int dir_id = dirs_.Add(dir); | |
| 244 return base::StringPrintf("%d:", dir_id); | |
| 245 } | |
| 246 | |
| 247 void MojoEnv::UnregisterDirectory(base::StringPiece prefix) { | |
| 248 DCHECK(!prefix.empty()); | |
| 249 DCHECK_EQ(prefix.back(), ':'); | |
| 250 prefix.remove_suffix(1); | |
| 251 int dir_id; | |
| 252 bool result = base::StringToInt(prefix, &dir_id); | |
| 253 DCHECK(result) << "Invalid directory id '" << prefix << "'"; | |
| 254 LevelDBMojoProxy::OpaqueDir* dir = dirs_.Lookup(dir_id); | |
| 255 DCHECK(dir) << "Invalid directory id " << dir_id; | |
| 256 dirs_.Remove(dir_id); | |
| 257 thread_->UnregisterDirectory(dir); | |
| 227 } | 258 } |
| 228 | 259 |
| 229 Status MojoEnv::NewSequentialFile(const std::string& fname, | 260 Status MojoEnv::NewSequentialFile(const std::string& fname, |
| 230 SequentialFile** result) { | 261 SequentialFile** result) { |
| 231 TRACE_EVENT1("leveldb", "MojoEnv::NewSequentialFile", "fname", fname); | 262 TRACE_EVENT1("leveldb", "MojoEnv::NewSequentialFile", "fname", fname); |
| 263 LevelDBMojoProxy::OpaqueDir* dir; | |
| 264 std::string path; | |
| 265 ParsePath(fname, &dir, &path); | |
| 266 | |
| 232 base::File f = thread_->OpenFileHandle( | 267 base::File f = thread_->OpenFileHandle( |
| 233 dir_, fname, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead); | 268 dir, path, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead); |
| 234 if (!f.IsValid()) { | 269 if (!f.IsValid()) { |
| 235 *result = nullptr; | 270 *result = nullptr; |
| 236 return MakeIOError(fname, "Unable to create sequential file", | 271 return MakeIOError(fname, "Unable to create sequential file", |
| 237 leveldb_env::kNewSequentialFile, f.error_details()); | 272 leveldb_env::kNewSequentialFile, f.error_details()); |
| 238 } | 273 } |
| 239 | 274 |
| 240 *result = new MojoSequentialFile(fname, std::move(f)); | 275 *result = new MojoSequentialFile(fname, std::move(f)); |
| 241 return Status::OK(); | 276 return Status::OK(); |
| 242 } | 277 } |
| 243 | 278 |
| 244 Status MojoEnv::NewRandomAccessFile(const std::string& fname, | 279 Status MojoEnv::NewRandomAccessFile(const std::string& fname, |
| 245 RandomAccessFile** result) { | 280 RandomAccessFile** result) { |
| 246 TRACE_EVENT1("leveldb", "MojoEnv::NewRandomAccessFile", "fname", fname); | 281 TRACE_EVENT1("leveldb", "MojoEnv::NewRandomAccessFile", "fname", fname); |
| 282 LevelDBMojoProxy::OpaqueDir* dir; | |
| 283 std::string path; | |
| 284 ParsePath(fname, &dir, &path); | |
| 285 | |
| 247 base::File f = thread_->OpenFileHandle( | 286 base::File f = thread_->OpenFileHandle( |
| 248 dir_, fname, filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen); | 287 dir, path, filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen); |
| 249 if (!f.IsValid()) { | 288 if (!f.IsValid()) { |
| 250 *result = nullptr; | 289 *result = nullptr; |
| 251 base::File::Error error_code = f.error_details(); | 290 base::File::Error error_code = f.error_details(); |
| 252 return MakeIOError(fname, FileErrorString(error_code), | 291 return MakeIOError(path, FileErrorString(error_code), |
| 253 leveldb_env::kNewRandomAccessFile, error_code); | 292 leveldb_env::kNewRandomAccessFile, error_code); |
| 254 } | 293 } |
| 255 | 294 |
| 256 *result = new MojoRandomAccessFile(fname, std::move(f)); | 295 *result = new MojoRandomAccessFile(path, std::move(f)); |
| 257 return Status::OK(); | 296 return Status::OK(); |
| 258 } | 297 } |
| 259 | 298 |
| 260 Status MojoEnv::NewWritableFile(const std::string& fname, | 299 Status MojoEnv::NewWritableFile(const std::string& fname, |
| 261 WritableFile** result) { | 300 WritableFile** result) { |
| 262 TRACE_EVENT1("leveldb", "MojoEnv::NewWritableFile", "fname", fname); | 301 TRACE_EVENT1("leveldb", "MojoEnv::NewWritableFile", "fname", fname); |
| 263 base::File f = | 302 LevelDBMojoProxy::OpaqueDir* dir; |
| 264 thread_->OpenFileHandle(dir_, fname, filesystem::mojom::kCreateAlways | | 303 std::string path; |
| 265 filesystem::mojom::kFlagWrite); | 304 ParsePath(fname, &dir, &path); |
| 305 | |
| 306 base::File f = thread_->OpenFileHandle( | |
| 307 dir, path, | |
| 308 filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite); | |
| 266 if (!f.IsValid()) { | 309 if (!f.IsValid()) { |
| 267 *result = nullptr; | 310 *result = nullptr; |
| 268 return MakeIOError(fname, "Unable to create writable file", | 311 return MakeIOError(path, "Unable to create writable file", |
| 269 leveldb_env::kNewWritableFile, f.error_details()); | 312 leveldb_env::kNewWritableFile, f.error_details()); |
| 270 } | 313 } |
| 271 | 314 |
| 272 *result = new MojoWritableFile(dir_, fname, std::move(f), thread_); | 315 *result = new MojoWritableFile(dir, path, std::move(f), thread_); |
| 273 return Status::OK(); | 316 return Status::OK(); |
| 274 } | 317 } |
| 275 | 318 |
| 276 Status MojoEnv::NewAppendableFile(const std::string& fname, | 319 Status MojoEnv::NewAppendableFile(const std::string& fname, |
| 277 WritableFile** result) { | 320 WritableFile** result) { |
| 278 TRACE_EVENT1("leveldb", "MojoEnv::NewAppendableFile", "fname", fname); | 321 TRACE_EVENT1("leveldb", "MojoEnv::NewAppendableFile", "fname", fname); |
| 279 base::File f = | 322 LevelDBMojoProxy::OpaqueDir* dir; |
| 280 thread_->OpenFileHandle(dir_, fname, filesystem::mojom::kFlagOpenAlways | | 323 std::string path; |
| 281 filesystem::mojom::kFlagAppend); | 324 ParsePath(fname, &dir, &path); |
| 325 | |
| 326 base::File f = thread_->OpenFileHandle( | |
| 327 dir, path, | |
| 328 filesystem::mojom::kFlagOpenAlways | filesystem::mojom::kFlagAppend); | |
| 282 if (!f.IsValid()) { | 329 if (!f.IsValid()) { |
| 283 *result = nullptr; | 330 *result = nullptr; |
| 284 return MakeIOError(fname, "Unable to create appendable file", | 331 return MakeIOError(path, "Unable to create appendable file", |
| 285 leveldb_env::kNewAppendableFile, f.error_details()); | 332 leveldb_env::kNewAppendableFile, f.error_details()); |
| 286 } | 333 } |
| 287 | 334 |
| 288 *result = new MojoWritableFile(dir_, fname, std::move(f), thread_); | 335 *result = new MojoWritableFile(dir, path, std::move(f), thread_); |
| 289 return Status::OK(); | 336 return Status::OK(); |
| 290 } | 337 } |
| 291 | 338 |
| 292 bool MojoEnv::FileExists(const std::string& fname) { | 339 bool MojoEnv::FileExists(const std::string& fname) { |
| 293 TRACE_EVENT1("leveldb", "MojoEnv::FileExists", "fname", fname); | 340 TRACE_EVENT1("leveldb", "MojoEnv::FileExists", "fname", fname); |
| 294 return thread_->FileExists(dir_, fname); | 341 LevelDBMojoProxy::OpaqueDir* dir; |
| 342 std::string path; | |
| 343 ParsePath(fname, &dir, &path); | |
| 344 | |
| 345 return thread_->FileExists(dir, path); | |
| 295 } | 346 } |
| 296 | 347 |
| 297 Status MojoEnv::GetChildren(const std::string& path, | 348 Status MojoEnv::GetChildren(const std::string& dirname, |
| 298 std::vector<std::string>* result) { | 349 std::vector<std::string>* result) { |
| 299 TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "path", path); | 350 TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "dirname", dirname); |
| 300 return FilesystemErrorToStatus(thread_->GetChildren(dir_, path, result), path, | 351 LevelDBMojoProxy::OpaqueDir* dir; |
| 352 std::string path; | |
| 353 ParsePath(dirname, &dir, &path); | |
| 354 | |
| 355 return FilesystemErrorToStatus(thread_->GetChildren(dir, path, result), path, | |
| 301 leveldb_env::kGetChildren); | 356 leveldb_env::kGetChildren); |
| 302 } | 357 } |
| 303 | 358 |
| 304 Status MojoEnv::DeleteFile(const std::string& fname) { | 359 Status MojoEnv::DeleteFile(const std::string& fname) { |
| 305 TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname); | 360 TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname); |
| 306 return FilesystemErrorToStatus(thread_->Delete(dir_, fname, 0), fname, | 361 LevelDBMojoProxy::OpaqueDir* dir; |
| 362 std::string path; | |
| 363 ParsePath(fname, &dir, &path); | |
| 364 | |
| 365 return FilesystemErrorToStatus(thread_->Delete(dir, path, 0), path, | |
| 307 leveldb_env::kDeleteFile); | 366 leveldb_env::kDeleteFile); |
| 308 } | 367 } |
| 309 | 368 |
| 310 Status MojoEnv::CreateDir(const std::string& dirname) { | 369 Status MojoEnv::CreateDir(const std::string& dirname) { |
| 311 TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname); | 370 TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname); |
| 312 return FilesystemErrorToStatus(thread_->CreateDir(dir_, dirname), dirname, | 371 LevelDBMojoProxy::OpaqueDir* dir; |
| 372 std::string path; | |
| 373 ParsePath(dirname, &dir, &path); | |
| 374 | |
| 375 return FilesystemErrorToStatus(thread_->CreateDir(dir, path), path, | |
| 313 leveldb_env::kCreateDir); | 376 leveldb_env::kCreateDir); |
| 314 } | 377 } |
| 315 | 378 |
| 316 Status MojoEnv::DeleteDir(const std::string& dirname) { | 379 Status MojoEnv::DeleteDir(const std::string& dirname) { |
| 317 TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname); | 380 TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname); |
| 381 LevelDBMojoProxy::OpaqueDir* dir; | |
| 382 std::string path; | |
| 383 ParsePath(dirname, &dir, &path); | |
| 384 | |
| 318 return FilesystemErrorToStatus( | 385 return FilesystemErrorToStatus( |
| 319 thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive), | 386 thread_->Delete(dir, path, filesystem::mojom::kDeleteFlagRecursive), path, |
| 320 dirname, leveldb_env::kDeleteDir); | 387 leveldb_env::kDeleteDir); |
| 321 } | 388 } |
| 322 | 389 |
| 323 Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) { | 390 Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) { |
| 324 TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname); | 391 TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname); |
| 325 return FilesystemErrorToStatus(thread_->GetFileSize(dir_, fname, file_size), | 392 LevelDBMojoProxy::OpaqueDir* dir; |
| 326 fname, | 393 std::string path; |
| 327 leveldb_env::kGetFileSize); | 394 ParsePath(fname, &dir, &path); |
| 395 | |
| 396 return FilesystemErrorToStatus(thread_->GetFileSize(dir, path, file_size), | |
| 397 path, leveldb_env::kGetFileSize); | |
| 328 } | 398 } |
| 329 | 399 |
| 330 Status MojoEnv::RenameFile(const std::string& src, const std::string& target) { | 400 Status MojoEnv::RenameFile(const std::string& src, const std::string& target) { |
| 331 TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target); | 401 TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target); |
| 332 return FilesystemErrorToStatus(thread_->RenameFile(dir_, src, target), src, | 402 LevelDBMojoProxy::OpaqueDir* src_dir; |
| 333 leveldb_env::kRenameFile); | 403 std::string src_path; |
| 404 ParsePath(src, &src_dir, &src_path); | |
| 405 LevelDBMojoProxy::OpaqueDir* target_dir; | |
| 406 std::string target_path; | |
| 407 ParsePath(target, &target_dir, &target_path); | |
| 408 DCHECK_EQ(src_dir, target_dir); | |
| 409 | |
| 410 return FilesystemErrorToStatus( | |
| 411 thread_->RenameFile(src_dir, src_path, target_path), src_path, | |
| 412 leveldb_env::kRenameFile); | |
| 334 } | 413 } |
| 335 | 414 |
| 336 Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) { | 415 Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) { |
| 337 TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname); | 416 TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname); |
| 417 LevelDBMojoProxy::OpaqueDir* dir; | |
| 418 std::string path; | |
| 419 ParsePath(fname, &dir, &path); | |
| 338 | 420 |
| 339 std::pair<filesystem::mojom::FileError, LevelDBMojoProxy::OpaqueLock*> p = | 421 std::pair<filesystem::mojom::FileError, LevelDBMojoProxy::OpaqueLock*> p = |
| 340 thread_->LockFile(dir_, fname); | 422 thread_->LockFile(dir, path); |
| 341 | 423 |
| 342 if (p.second) | 424 if (p.second) |
| 343 *lock = new MojoFileLock(p.second, fname); | 425 *lock = new MojoFileLock(p.second, fname); |
| 344 | 426 |
| 345 return FilesystemErrorToStatus(p.first, fname, leveldb_env::kLockFile); | 427 return FilesystemErrorToStatus(p.first, path, leveldb_env::kLockFile); |
| 346 } | 428 } |
| 347 | 429 |
| 348 Status MojoEnv::UnlockFile(FileLock* lock) { | 430 Status MojoEnv::UnlockFile(FileLock* lock) { |
| 349 MojoFileLock* my_lock = reinterpret_cast<MojoFileLock*>(lock); | 431 MojoFileLock* my_lock = reinterpret_cast<MojoFileLock*>(lock); |
| 350 | 432 |
| 351 std::string fname = my_lock ? my_lock->name() : "(invalid)"; | 433 std::string fname = my_lock ? my_lock->name() : "(invalid)"; |
| 352 TRACE_EVENT1("leveldb", "MojoEnv::UnlockFile", "fname", fname); | 434 TRACE_EVENT1("leveldb", "MojoEnv::UnlockFile", "fname", fname); |
| 353 | 435 |
| 354 filesystem::mojom::FileError err = thread_->UnlockFile(my_lock->TakeLock()); | 436 filesystem::mojom::FileError err = thread_->UnlockFile(my_lock->TakeLock()); |
| 355 delete my_lock; | 437 delete my_lock; |
| 356 return FilesystemErrorToStatus(err, fname, leveldb_env::kUnlockFile); | 438 return FilesystemErrorToStatus(err, fname, leveldb_env::kUnlockFile); |
| 357 } | 439 } |
| 358 | 440 |
| 359 Status MojoEnv::GetTestDirectory(std::string* path) { | 441 Status MojoEnv::GetTestDirectory(std::string* path) { |
| 360 // TODO(erg): This method is actually only used from the test harness in | 442 // TODO(erg): This method is actually only used from the test harness in |
| 361 // leveldb. And when we go and port that test stuff to a | 443 // leveldb. And when we go and port that test stuff to a |
| 362 // service_manager::ServiceTest, | 444 // service_manager::ServiceTest, |
| 363 // we probably won't use it since the mojo filesystem actually handles | 445 // we probably won't use it since the mojo filesystem actually handles |
| 364 // temporary filesystems just fine. | 446 // temporary filesystems just fine. |
| 365 NOTREACHED(); | 447 NOTREACHED(); |
| 366 return Status::OK(); | 448 return Status::OK(); |
| 367 } | 449 } |
| 368 | 450 |
| 369 Status MojoEnv::NewLogger(const std::string& fname, Logger** result) { | 451 Status MojoEnv::NewLogger(const std::string& fname, Logger** result) { |
| 370 TRACE_EVENT1("leveldb", "MojoEnv::NewLogger", "fname", fname); | 452 TRACE_EVENT1("leveldb", "MojoEnv::NewLogger", "fname", fname); |
| 453 LevelDBMojoProxy::OpaqueDir* dir; | |
| 454 std::string path; | |
| 455 ParsePath(fname, &dir, &path); | |
| 456 | |
| 371 base::File f(thread_->OpenFileHandle( | 457 base::File f(thread_->OpenFileHandle( |
| 372 dir_, fname, | 458 dir, path, |
| 373 filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite)); | 459 filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite)); |
| 374 if (!f.IsValid()) { | 460 if (!f.IsValid()) { |
| 375 *result = NULL; | 461 *result = NULL; |
| 376 return MakeIOError(fname, "Unable to create log file", | 462 return MakeIOError(path, "Unable to create log file", |
| 377 leveldb_env::kNewLogger, f.error_details()); | 463 leveldb_env::kNewLogger, f.error_details()); |
| 378 } else { | 464 } else { |
| 379 *result = new leveldb::ChromiumLogger(std::move(f)); | 465 *result = new leveldb::ChromiumLogger(std::move(f)); |
| 380 return Status::OK(); | 466 return Status::OK(); |
| 381 } | 467 } |
| 382 } | 468 } |
| 383 | 469 |
| 470 void MojoEnv::ParsePath(const std::string& path, | |
| 471 LevelDBMojoProxy::OpaqueDir** out_dir, | |
| 472 std::string* out_path) { | |
| 473 size_t colon_pos = path.find(':'); | |
| 474 DCHECK_NE(colon_pos, std::string::npos); | |
| 475 | |
| 476 int dir_id; | |
| 477 bool result = base::StringToInt( | |
| 478 base::StringPiece(path.begin(), path.begin() + colon_pos), &dir_id); | |
| 479 DCHECK(result) << "Invalid directory id in path '" << path << "'"; | |
| 480 *out_dir = dirs_.Lookup(dir_id); | |
| 481 DCHECK(*out_dir) << "Invalid directory id " << dir_id; | |
| 482 | |
| 483 *out_path = std::string(path.begin() + colon_pos + 1, path.end()); | |
| 484 } | |
| 485 | |
| 486 MojoEnv::MojoEnv(scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) | |
| 487 : ChromiumEnv("LevelDBEnv.Mojo"), | |
| 488 thread_(new LevelDBMojoProxy(std::move(file_task_runner))) {} | |
| 489 | |
| 490 MojoEnv::~MojoEnv() {} | |
| 491 | |
| 384 } // namespace leveldb | 492 } // namespace leveldb |
| OLD | NEW |