OLD | NEW |
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. | 1 // Copyright (c) 2011 The LevelDB 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. See the AUTHORS file for names of contributors. | 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. |
4 | 4 |
5 #include <deque> | 5 #include <deque> |
6 #include <errno.h> | 6 #include <errno.h> |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include "base/at_exit.h" | 8 #include "base/at_exit.h" |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 kRenamefile, | 119 kRenamefile, |
120 kLockFile, | 120 kLockFile, |
121 kUnlockFile, | 121 kUnlockFile, |
122 kGetTestDirectory, | 122 kGetTestDirectory, |
123 kNewLogger, | 123 kNewLogger, |
124 kNumEntries | 124 kNumEntries |
125 }; | 125 }; |
126 | 126 |
127 class UMALogger { | 127 class UMALogger { |
128 public: | 128 public: |
129 UMALogger(std::string uma_title); | 129 virtual void RecordErrorAt(UmaEntry entry) const = 0; |
130 void RecordErrorAt(UmaEntry entry) const; | 130 virtual void LogRandomAccessFileError(base::PlatformFileError error_code) |
131 void LogRandomAccessFileError(base::PlatformFileError error_code) const; | 131 const = 0; |
132 | |
133 private: | |
134 std::string uma_title_; | |
135 }; | 132 }; |
136 | 133 |
137 UMALogger::UMALogger(std::string uma_title) : uma_title_(uma_title) {} | |
138 | |
139 void UMALogger::RecordErrorAt(UmaEntry entry) const { | |
140 std::string uma_name(uma_title_); | |
141 uma_name.append(".IOError"); | |
142 UMA_HISTOGRAM_ENUMERATION(uma_name, entry, kNumEntries); | |
143 } | |
144 | |
145 void UMALogger::LogRandomAccessFileError(base::PlatformFileError error_code) | |
146 const { | |
147 DCHECK(error_code < 0); | |
148 std::string uma_name(uma_title_); | |
149 uma_name.append(".IOError.RandomAccessFile"); | |
150 UMA_HISTOGRAM_ENUMERATION(uma_name, | |
151 -error_code, | |
152 -base::PLATFORM_FILE_ERROR_MAX); | |
153 } | |
154 | |
155 } // namespace | 134 } // namespace |
156 | 135 |
157 namespace leveldb { | 136 namespace leveldb { |
158 | 137 |
159 namespace { | 138 namespace { |
160 | 139 |
161 class Thread; | 140 class Thread; |
162 | 141 |
163 static const ::FilePath::CharType kLevelDBTestDirectoryPrefix[] | 142 static const ::FilePath::CharType kLevelDBTestDirectoryPrefix[] |
164 = FILE_PATH_LITERAL("leveldb-test-"); | 143 = FILE_PATH_LITERAL("leveldb-test-"); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 } | 310 } |
332 return result; | 311 return result; |
333 } | 312 } |
334 }; | 313 }; |
335 | 314 |
336 class ChromiumFileLock : public FileLock { | 315 class ChromiumFileLock : public FileLock { |
337 public: | 316 public: |
338 ::base::PlatformFile file_; | 317 ::base::PlatformFile file_; |
339 }; | 318 }; |
340 | 319 |
341 class ChromiumEnv : public Env { | 320 class ChromiumEnv : public Env, public UMALogger { |
342 public: | 321 public: |
343 ChromiumEnv(); | 322 ChromiumEnv(); |
344 virtual ~ChromiumEnv() { | 323 virtual ~ChromiumEnv() { |
345 NOTREACHED(); | 324 NOTREACHED(); |
346 } | 325 } |
347 | 326 |
348 virtual Status NewSequentialFile(const std::string& fname, | 327 virtual Status NewSequentialFile(const std::string& fname, |
349 SequentialFile** result) { | 328 SequentialFile** result) { |
350 FILE* f = fopen_internal(fname.c_str(), "rb"); | 329 FILE* f = fopen_internal(fname.c_str(), "rb"); |
351 if (f == NULL) { | 330 if (f == NULL) { |
352 *result = NULL; | 331 *result = NULL; |
353 uma_logger_->RecordErrorAt(kNewSequentialFile); | 332 RecordErrorAt(kNewSequentialFile); |
354 return Status::IOError(fname, strerror(errno)); | 333 return Status::IOError(fname, strerror(errno)); |
355 } else { | 334 } else { |
356 *result = new ChromiumSequentialFile(fname, f, uma_logger_.get()); | 335 *result = new ChromiumSequentialFile(fname, f, this); |
357 return Status::OK(); | 336 return Status::OK(); |
358 } | 337 } |
359 } | 338 } |
360 | 339 |
361 virtual Status NewRandomAccessFile(const std::string& fname, | 340 virtual Status NewRandomAccessFile(const std::string& fname, |
362 RandomAccessFile** result) { | 341 RandomAccessFile** result) { |
363 int flags = ::base::PLATFORM_FILE_READ | ::base::PLATFORM_FILE_OPEN; | 342 int flags = ::base::PLATFORM_FILE_READ | ::base::PLATFORM_FILE_OPEN; |
364 bool created; | 343 bool created; |
365 ::base::PlatformFileError error_code; | 344 ::base::PlatformFileError error_code; |
366 ::base::PlatformFile file = ::base::CreatePlatformFile( | 345 ::base::PlatformFile file = ::base::CreatePlatformFile( |
367 CreateFilePath(fname), flags, &created, &error_code); | 346 CreateFilePath(fname), flags, &created, &error_code); |
368 if (error_code != ::base::PLATFORM_FILE_OK) { | 347 if (error_code != ::base::PLATFORM_FILE_OK) { |
369 *result = NULL; | 348 *result = NULL; |
370 uma_logger_->RecordErrorAt(kNewRandomAccessFile); | 349 RecordErrorAt(kNewRandomAccessFile); |
371 uma_logger_->LogRandomAccessFileError(error_code); | 350 LogRandomAccessFileError(error_code); |
372 return Status::IOError(fname, PlatformFileErrorString(error_code)); | 351 return Status::IOError(fname, PlatformFileErrorString(error_code)); |
373 } | 352 } |
374 *result = new ChromiumRandomAccessFile(fname, file, uma_logger_.get()); | 353 *result = new ChromiumRandomAccessFile(fname, file, this); |
375 return Status::OK(); | 354 return Status::OK(); |
376 } | 355 } |
377 | 356 |
378 virtual Status NewWritableFile(const std::string& fname, | 357 virtual Status NewWritableFile(const std::string& fname, |
379 WritableFile** result) { | 358 WritableFile** result) { |
380 *result = NULL; | 359 *result = NULL; |
381 FILE* f = fopen_internal(fname.c_str(), "wb"); | 360 FILE* f = fopen_internal(fname.c_str(), "wb"); |
382 if (f == NULL) { | 361 if (f == NULL) { |
383 uma_logger_->RecordErrorAt(kNewWritableFile); | 362 RecordErrorAt(kNewWritableFile); |
384 return Status::IOError(fname, strerror(errno)); | 363 return Status::IOError(fname, strerror(errno)); |
385 } else { | 364 } else { |
386 if (!sync_parent(fname)) { | 365 if (!sync_parent(fname)) { |
387 fclose(f); | 366 fclose(f); |
388 return Status::IOError(fname, strerror(errno)); | 367 return Status::IOError(fname, strerror(errno)); |
389 } | 368 } |
390 *result = new ChromiumWritableFile(fname, f, uma_logger_.get()); | 369 *result = new ChromiumWritableFile(fname, f, this); |
391 return Status::OK(); | 370 return Status::OK(); |
392 } | 371 } |
393 } | 372 } |
394 | 373 |
395 virtual bool FileExists(const std::string& fname) { | 374 virtual bool FileExists(const std::string& fname) { |
396 return ::file_util::PathExists(CreateFilePath(fname)); | 375 return ::file_util::PathExists(CreateFilePath(fname)); |
397 } | 376 } |
398 | 377 |
399 virtual Status GetChildren(const std::string& dir, | 378 virtual Status GetChildren(const std::string& dir, |
400 std::vector<std::string>* result) { | 379 std::vector<std::string>* result) { |
401 result->clear(); | 380 result->clear(); |
402 ::file_util::FileEnumerator iter( | 381 ::file_util::FileEnumerator iter( |
403 CreateFilePath(dir), false, ::file_util::FileEnumerator::FILES); | 382 CreateFilePath(dir), false, ::file_util::FileEnumerator::FILES); |
404 ::FilePath current = iter.Next(); | 383 ::FilePath current = iter.Next(); |
405 while (!current.empty()) { | 384 while (!current.empty()) { |
406 result->push_back(FilePathToString(current.BaseName())); | 385 result->push_back(FilePathToString(current.BaseName())); |
407 current = iter.Next(); | 386 current = iter.Next(); |
408 } | 387 } |
409 // TODO(jorlow): Unfortunately, the FileEnumerator swallows errors, so | 388 // TODO(jorlow): Unfortunately, the FileEnumerator swallows errors, so |
410 // we'll always return OK. Maybe manually check for error | 389 // we'll always return OK. Maybe manually check for error |
411 // conditions like the file not existing? | 390 // conditions like the file not existing? |
412 return Status::OK(); | 391 return Status::OK(); |
413 } | 392 } |
414 | 393 |
415 virtual Status DeleteFile(const std::string& fname) { | 394 virtual Status DeleteFile(const std::string& fname) { |
416 Status result; | 395 Status result; |
417 // TODO(jorlow): Should we assert this is a file? | 396 // TODO(jorlow): Should we assert this is a file? |
418 if (!::file_util::Delete(CreateFilePath(fname), false)) { | 397 if (!::file_util::Delete(CreateFilePath(fname), false)) { |
419 result = Status::IOError(fname, "Could not delete file."); | 398 result = Status::IOError(fname, "Could not delete file."); |
420 uma_logger_->RecordErrorAt(kDeleteFile); | 399 RecordErrorAt(kDeleteFile); |
421 } | 400 } |
422 return result; | 401 return result; |
423 }; | 402 }; |
424 | 403 |
425 virtual Status CreateDir(const std::string& name) { | 404 virtual Status CreateDir(const std::string& name) { |
426 Status result; | 405 Status result; |
427 if (!::file_util::CreateDirectory(CreateFilePath(name))) { | 406 if (!::file_util::CreateDirectory(CreateFilePath(name))) { |
428 result = Status::IOError(name, "Could not create directory."); | 407 result = Status::IOError(name, "Could not create directory."); |
429 uma_logger_->RecordErrorAt(kCreateDir); | 408 RecordErrorAt(kCreateDir); |
430 } | 409 } |
431 return result; | 410 return result; |
432 }; | 411 }; |
433 | 412 |
434 virtual Status DeleteDir(const std::string& name) { | 413 virtual Status DeleteDir(const std::string& name) { |
435 Status result; | 414 Status result; |
436 // TODO(jorlow): Should we assert this is a directory? | 415 // TODO(jorlow): Should we assert this is a directory? |
437 if (!::file_util::Delete(CreateFilePath(name), false)) { | 416 if (!::file_util::Delete(CreateFilePath(name), false)) { |
438 result = Status::IOError(name, "Could not delete directory."); | 417 result = Status::IOError(name, "Could not delete directory."); |
439 uma_logger_->RecordErrorAt(kDeleteDir); | 418 RecordErrorAt(kDeleteDir); |
440 } | 419 } |
441 return result; | 420 return result; |
442 }; | 421 }; |
443 | 422 |
444 virtual Status GetFileSize(const std::string& fname, uint64_t* size) { | 423 virtual Status GetFileSize(const std::string& fname, uint64_t* size) { |
445 Status s; | 424 Status s; |
446 int64_t signed_size; | 425 int64_t signed_size; |
447 if (!::file_util::GetFileSize(CreateFilePath(fname), &signed_size)) { | 426 if (!::file_util::GetFileSize(CreateFilePath(fname), &signed_size)) { |
448 *size = 0; | 427 *size = 0; |
449 s = Status::IOError(fname, "Could not determine file size."); | 428 s = Status::IOError(fname, "Could not determine file size."); |
450 uma_logger_->RecordErrorAt(kGetFileSize); | 429 RecordErrorAt(kGetFileSize); |
451 } else { | 430 } else { |
452 *size = static_cast<uint64_t>(signed_size); | 431 *size = static_cast<uint64_t>(signed_size); |
453 } | 432 } |
454 return s; | 433 return s; |
455 } | 434 } |
456 | 435 |
457 virtual Status RenameFile(const std::string& src, const std::string& dst) { | 436 virtual Status RenameFile(const std::string& src, const std::string& dst) { |
458 Status result; | 437 Status result; |
459 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) { | 438 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) { |
460 result = Status::IOError(src, "Could not rename file."); | 439 result = Status::IOError(src, "Could not rename file."); |
461 uma_logger_->RecordErrorAt(kRenamefile); | 440 RecordErrorAt(kRenamefile); |
462 } else { | 441 } else { |
463 sync_parent(dst); | 442 sync_parent(dst); |
464 if (src != dst) | 443 if (src != dst) |
465 sync_parent(src); | 444 sync_parent(src); |
466 } | 445 } |
467 return result; | 446 return result; |
468 } | 447 } |
469 | 448 |
470 virtual Status LockFile(const std::string& fname, FileLock** lock) { | 449 virtual Status LockFile(const std::string& fname, FileLock** lock) { |
471 *lock = NULL; | 450 *lock = NULL; |
472 Status result; | 451 Status result; |
473 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS | | 452 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS | |
474 ::base::PLATFORM_FILE_READ | | 453 ::base::PLATFORM_FILE_READ | |
475 ::base::PLATFORM_FILE_WRITE | | 454 ::base::PLATFORM_FILE_WRITE | |
476 ::base::PLATFORM_FILE_EXCLUSIVE_READ | | 455 ::base::PLATFORM_FILE_EXCLUSIVE_READ | |
477 ::base::PLATFORM_FILE_EXCLUSIVE_WRITE; | 456 ::base::PLATFORM_FILE_EXCLUSIVE_WRITE; |
478 bool created; | 457 bool created; |
479 ::base::PlatformFileError error_code; | 458 ::base::PlatformFileError error_code; |
480 ::base::PlatformFile file = ::base::CreatePlatformFile( | 459 ::base::PlatformFile file = ::base::CreatePlatformFile( |
481 CreateFilePath(fname), flags, &created, &error_code); | 460 CreateFilePath(fname), flags, &created, &error_code); |
482 if (error_code != ::base::PLATFORM_FILE_OK) { | 461 if (error_code != ::base::PLATFORM_FILE_OK) { |
483 result = Status::IOError(fname, PlatformFileErrorString(error_code)); | 462 result = Status::IOError(fname, PlatformFileErrorString(error_code)); |
484 uma_logger_->RecordErrorAt(kLockFile); | 463 RecordErrorAt(kLockFile); |
485 } else { | 464 } else { |
486 ChromiumFileLock* my_lock = new ChromiumFileLock; | 465 ChromiumFileLock* my_lock = new ChromiumFileLock; |
487 my_lock->file_ = file; | 466 my_lock->file_ = file; |
488 *lock = my_lock; | 467 *lock = my_lock; |
489 } | 468 } |
490 return result; | 469 return result; |
491 } | 470 } |
492 | 471 |
493 virtual Status UnlockFile(FileLock* lock) { | 472 virtual Status UnlockFile(FileLock* lock) { |
494 ChromiumFileLock* my_lock = reinterpret_cast<ChromiumFileLock*>(lock); | 473 ChromiumFileLock* my_lock = reinterpret_cast<ChromiumFileLock*>(lock); |
495 Status result; | 474 Status result; |
496 if (!::base::ClosePlatformFile(my_lock->file_)) { | 475 if (!::base::ClosePlatformFile(my_lock->file_)) { |
497 result = Status::IOError("Could not close lock file."); | 476 result = Status::IOError("Could not close lock file."); |
498 uma_logger_->RecordErrorAt(kUnlockFile); | 477 RecordErrorAt(kUnlockFile); |
499 } | 478 } |
500 delete my_lock; | 479 delete my_lock; |
501 return result; | 480 return result; |
502 } | 481 } |
503 | 482 |
504 virtual void Schedule(void (*function)(void*), void* arg); | 483 virtual void Schedule(void (*function)(void*), void* arg); |
505 | 484 |
506 virtual void StartThread(void (*function)(void* arg), void* arg); | 485 virtual void StartThread(void (*function)(void* arg), void* arg); |
507 | 486 |
508 virtual std::string UserIdentifier() { | 487 virtual std::string UserIdentifier() { |
509 #if defined(OS_WIN) | 488 #if defined(OS_WIN) |
510 std::wstring user_sid; | 489 std::wstring user_sid; |
511 bool ret = ::base::win::GetUserSidString(&user_sid); | 490 bool ret = ::base::win::GetUserSidString(&user_sid); |
512 DCHECK(ret); | 491 DCHECK(ret); |
513 return UTF16ToUTF8(user_sid); | 492 return UTF16ToUTF8(user_sid); |
514 #else | 493 #else |
515 char buf[100]; | 494 char buf[100]; |
516 snprintf(buf, sizeof(buf), "%d", int(geteuid())); | 495 snprintf(buf, sizeof(buf), "%d", int(geteuid())); |
517 return buf; | 496 return buf; |
518 #endif | 497 #endif |
519 } | 498 } |
520 | 499 |
521 virtual Status GetTestDirectory(std::string* path) { | 500 virtual Status GetTestDirectory(std::string* path) { |
522 mu_.Acquire(); | 501 mu_.Acquire(); |
523 if (test_directory_.empty()) { | 502 if (test_directory_.empty()) { |
524 if (!::file_util::CreateNewTempDirectory(kLevelDBTestDirectoryPrefix, | 503 if (!::file_util::CreateNewTempDirectory(kLevelDBTestDirectoryPrefix, |
525 &test_directory_)) { | 504 &test_directory_)) { |
526 mu_.Release(); | 505 mu_.Release(); |
527 uma_logger_->RecordErrorAt(kGetTestDirectory); | 506 RecordErrorAt(kGetTestDirectory); |
528 return Status::IOError("Could not create temp directory."); | 507 return Status::IOError("Could not create temp directory."); |
529 } | 508 } |
530 } | 509 } |
531 *path = FilePathToString(test_directory_); | 510 *path = FilePathToString(test_directory_); |
532 mu_.Release(); | 511 mu_.Release(); |
533 return Status::OK(); | 512 return Status::OK(); |
534 } | 513 } |
535 | 514 |
536 virtual Status NewLogger(const std::string& fname, Logger** result) { | 515 virtual Status NewLogger(const std::string& fname, Logger** result) { |
537 FILE* f = fopen_internal(fname.c_str(), "w"); | 516 FILE* f = fopen_internal(fname.c_str(), "w"); |
538 if (f == NULL) { | 517 if (f == NULL) { |
539 *result = NULL; | 518 *result = NULL; |
540 uma_logger_->RecordErrorAt(kNewLogger); | 519 RecordErrorAt(kNewLogger); |
541 return Status::IOError(fname, strerror(errno)); | 520 return Status::IOError(fname, strerror(errno)); |
542 } else { | 521 } else { |
543 if (!sync_parent(fname)) { | 522 if (!sync_parent(fname)) { |
544 fclose(f); | 523 fclose(f); |
545 return Status::IOError(fname, strerror(errno)); | 524 return Status::IOError(fname, strerror(errno)); |
546 } | 525 } |
547 *result = new ChromiumLogger(f); | 526 *result = new ChromiumLogger(f); |
548 return Status::OK(); | 527 return Status::OK(); |
549 } | 528 } |
550 } | 529 } |
551 | 530 |
552 virtual uint64_t NowMicros() { | 531 virtual uint64_t NowMicros() { |
553 return ::base::TimeTicks::Now().ToInternalValue(); | 532 return ::base::TimeTicks::Now().ToInternalValue(); |
554 } | 533 } |
555 | 534 |
556 virtual void SleepForMicroseconds(int micros) { | 535 virtual void SleepForMicroseconds(int micros) { |
557 // Round up to the next millisecond. | 536 // Round up to the next millisecond. |
558 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros)); | 537 ::base::PlatformThread::Sleep(::base::TimeDelta::FromMicroseconds(micros)); |
559 } | 538 } |
560 | 539 |
| 540 void RecordErrorAt(UmaEntry entry) const { |
| 541 io_error_histogram_->Add(entry); |
| 542 } |
| 543 |
| 544 void LogRandomAccessFileError(base::PlatformFileError error_code) const { |
| 545 DCHECK(error_code < 0); |
| 546 random_access_file_histogram_->Add(-error_code); |
| 547 } |
| 548 |
561 protected: | 549 protected: |
562 scoped_ptr<UMALogger> uma_logger_; | 550 void InitHistograms(const std::string& uma_title); |
563 | 551 |
564 private: | 552 private: |
565 // BGThread() is the body of the background thread | 553 // BGThread() is the body of the background thread |
566 void BGThread(); | 554 void BGThread(); |
567 static void BGThreadWrapper(void* arg) { | 555 static void BGThreadWrapper(void* arg) { |
568 reinterpret_cast<ChromiumEnv*>(arg)->BGThread(); | 556 reinterpret_cast<ChromiumEnv*>(arg)->BGThread(); |
569 } | 557 } |
570 | 558 |
571 FilePath test_directory_; | 559 FilePath test_directory_; |
572 | 560 |
573 size_t page_size_; | 561 size_t page_size_; |
574 ::base::Lock mu_; | 562 ::base::Lock mu_; |
575 ::base::ConditionVariable bgsignal_; | 563 ::base::ConditionVariable bgsignal_; |
576 bool started_bgthread_; | 564 bool started_bgthread_; |
577 | 565 |
578 // Entry per Schedule() call | 566 // Entry per Schedule() call |
579 struct BGItem { void* arg; void (*function)(void*); }; | 567 struct BGItem { void* arg; void (*function)(void*); }; |
580 typedef std::deque<BGItem> BGQueue; | 568 typedef std::deque<BGItem> BGQueue; |
581 BGQueue queue_; | 569 BGQueue queue_; |
| 570 |
| 571 base::Histogram* io_error_histogram_; |
| 572 base::Histogram* random_access_file_histogram_; |
582 }; | 573 }; |
583 | 574 |
584 ChromiumEnv::ChromiumEnv() | 575 ChromiumEnv::ChromiumEnv() |
585 : page_size_(::base::SysInfo::VMAllocationGranularity()), | 576 : page_size_(::base::SysInfo::VMAllocationGranularity()), |
586 bgsignal_(&mu_), | 577 bgsignal_(&mu_), |
587 started_bgthread_(false), | 578 started_bgthread_(false) { |
588 uma_logger_(new UMALogger("LevelDBEnv")) { | 579 InitHistograms("LevelDBEnv"); |
| 580 } |
| 581 |
| 582 void ChromiumEnv::InitHistograms(const std::string& uma_title) { |
| 583 std::string uma_name(uma_title); |
| 584 uma_name.append(".IOError"); |
| 585 // Note: The calls to FactoryGet aren't thread-safe. It's ok to call them here |
| 586 // because this method is only called from LazyInstance, which provides |
| 587 // thread-safety. |
| 588 io_error_histogram_ = base::LinearHistogram::FactoryGet(uma_name, 1, |
| 589 kNumEntries, kNumEntries + 1, base::Histogram::kUmaTargetedHistogramFlag); |
| 590 |
| 591 uma_name.append(".RandomAccessFile"); |
| 592 random_access_file_histogram_ = base::LinearHistogram::FactoryGet(uma_name, 1, |
| 593 -base::PLATFORM_FILE_ERROR_MAX, -base::PLATFORM_FILE_ERROR_MAX + 1, |
| 594 base::Histogram::kUmaTargetedHistogramFlag); |
589 } | 595 } |
590 | 596 |
591 class Thread : public ::base::PlatformThread::Delegate { | 597 class Thread : public ::base::PlatformThread::Delegate { |
592 public: | 598 public: |
593 Thread(void (*function)(void* arg), void* arg) | 599 Thread(void (*function)(void* arg), void* arg) |
594 : function_(function), arg_(arg) { | 600 : function_(function), arg_(arg) { |
595 ::base::PlatformThreadHandle handle; | 601 ::base::PlatformThreadHandle handle; |
596 bool success = ::base::PlatformThread::Create(0, this, &handle); | 602 bool success = ::base::PlatformThread::Create(0, this, &handle); |
597 DCHECK(success); | 603 DCHECK(success); |
598 } | 604 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 } | 653 } |
648 } | 654 } |
649 | 655 |
650 void ChromiumEnv::StartThread(void (*function)(void* arg), void* arg) { | 656 void ChromiumEnv::StartThread(void (*function)(void* arg), void* arg) { |
651 new Thread(function, arg); // Will self-delete. | 657 new Thread(function, arg); // Will self-delete. |
652 } | 658 } |
653 | 659 |
654 class IDBEnv : public ChromiumEnv { | 660 class IDBEnv : public ChromiumEnv { |
655 public: | 661 public: |
656 IDBEnv() : ChromiumEnv() { | 662 IDBEnv() : ChromiumEnv() { |
657 uma_logger_.reset(new UMALogger("LevelDBEnv.IDB")); | 663 InitHistograms("LevelDBEnv.IDB"); |
658 } | 664 } |
659 }; | 665 }; |
660 | 666 |
661 ::base::LazyInstance<IDBEnv>::Leaky | 667 ::base::LazyInstance<IDBEnv>::Leaky |
662 idb_env = LAZY_INSTANCE_INITIALIZER; | 668 idb_env = LAZY_INSTANCE_INITIALIZER; |
663 | 669 |
664 ::base::LazyInstance<ChromiumEnv>::Leaky | 670 ::base::LazyInstance<ChromiumEnv>::Leaky |
665 default_env = LAZY_INSTANCE_INITIALIZER; | 671 default_env = LAZY_INSTANCE_INITIALIZER; |
666 | 672 |
667 } | 673 } |
668 | 674 |
669 Env* IDBEnv() { | 675 Env* IDBEnv() { |
670 return idb_env.Pointer(); | 676 return idb_env.Pointer(); |
671 } | 677 } |
672 | 678 |
673 Env* Env::Default() { | 679 Env* Env::Default() { |
674 return default_env.Pointer(); | 680 return default_env.Pointer(); |
675 } | 681 } |
676 | 682 |
677 } | 683 } |
OLD | NEW |