diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/base.gypi | 4 | ||||
-rw-r--r-- | base/file_util.cc | 50 | ||||
-rw-r--r-- | base/file_util.h | 53 | ||||
-rw-r--r-- | base/file_util_posix.cc | 40 | ||||
-rw-r--r-- | base/file_util_win.cc | 76 | ||||
-rw-r--r-- | base/files/memory_mapped_file.cc | 58 | ||||
-rw-r--r-- | base/files/memory_mapped_file.h | 76 | ||||
-rw-r--r-- | base/files/memory_mapped_file_posix.cc | 54 | ||||
-rw-r--r-- | base/files/memory_mapped_file_win.cc | 87 | ||||
-rw-r--r-- | base/i18n/icu_util.cc | 3 | ||||
-rw-r--r-- | base/test/test_file_util_mac.cc | 4 |
11 files changed, 284 insertions, 221 deletions
diff --git a/base/base.gypi b/base/base.gypi index 35776f7..6e7013f 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -168,6 +168,10 @@ 'files/file_util_proxy.h', 'files/important_file_writer.h', 'files/important_file_writer.cc', + 'files/memory_mapped_file.cc', + 'files/memory_mapped_file.h', + 'files/memory_mapped_file_posix.cc', + 'files/memory_mapped_file_win.cc', 'files/scoped_temp_dir.cc', 'files/scoped_temp_dir.h', 'float_util.h', diff --git a/base/file_util.cc b/base/file_util.cc index b6cdc98..f951e3b 100644 --- a/base/file_util.cc +++ b/base/file_util.cc @@ -351,56 +351,6 @@ int64 ComputeFilesSize(const FilePath& directory, } /////////////////////////////////////////////// -// MemoryMappedFile - -MemoryMappedFile::~MemoryMappedFile() { - CloseHandles(); -} - -bool MemoryMappedFile::Initialize(const FilePath& file_name) { - if (IsValid()) - return false; - - if (!MapFileToMemory(file_name)) { - CloseHandles(); - return false; - } - - return true; -} - -bool MemoryMappedFile::Initialize(base::PlatformFile file) { - if (IsValid()) - return false; - - file_ = file; - - if (!MapFileToMemoryInternal()) { - CloseHandles(); - return false; - } - - return true; -} - -bool MemoryMappedFile::IsValid() const { - return data_ != NULL; -} - -bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { - file_ = base::CreatePlatformFile( - file_name, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, - NULL, NULL); - - if (file_ == base::kInvalidPlatformFileValue) { - DLOG(ERROR) << "Couldn't open " << file_name.value(); - return false; - } - - return MapFileToMemoryInternal(); -} - -/////////////////////////////////////////////// // FileEnumerator // // Note: the main logic is in file_util_<platform>.cc diff --git a/base/file_util.h b/base/file_util.h index e36456a..bd4b33d 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -560,59 +560,6 @@ class BASE_EXPORT FileEnumerator { DISALLOW_COPY_AND_ASSIGN(FileEnumerator); }; -class BASE_EXPORT MemoryMappedFile { - public: - // The default constructor sets all members to invalid/null values. - MemoryMappedFile(); - ~MemoryMappedFile(); - - // Opens an existing file and maps it into memory. Access is restricted to - // read only. If this object already points to a valid memory mapped file - // then this method will fail and return false. If it cannot open the file, - // the file does not exist, or the memory mapping fails, it will return false. - // Later we may want to allow the user to specify access. - bool Initialize(const base::FilePath& file_name); - // As above, but works with an already-opened file. MemoryMappedFile will take - // ownership of |file| and close it when done. - bool Initialize(base::PlatformFile file); - -#if defined(OS_WIN) - // Opens an existing file and maps it as an image section. Please refer to - // the Initialize function above for additional information. - bool InitializeAsImageSection(const base::FilePath& file_name); -#endif // OS_WIN - - const uint8* data() const { return data_; } - size_t length() const { return length_; } - - // Is file_ a valid file handle that points to an open, memory mapped file? - bool IsValid() const; - - private: - // Open the given file and pass it to MapFileToMemoryInternal(). - bool MapFileToMemory(const base::FilePath& file_name); - - // Map the file to memory, set data_ to that memory address. Return true on - // success, false on any kind of failure. This is a helper for Initialize(). - bool MapFileToMemoryInternal(); - - // Closes all open handles. Later we may want to make this public. - void CloseHandles(); - -#if defined(OS_WIN) - // MapFileToMemoryInternal calls this function. It provides the ability to - // pass in flags which control the mapped section. - bool MapFileToMemoryInternalEx(int flags); - - HANDLE file_mapping_; -#endif - base::PlatformFile file_; - uint8* data_; - size_t length_; - - DISALLOW_COPY_AND_ASSIGN(MemoryMappedFile); -}; - // Returns whether the file has been modified since a particular date. BASE_EXPORT bool HasFileBeenModifiedSince( const FileEnumerator::FindInfo& find_info, diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 974b30d..8b01412 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -859,46 +859,6 @@ bool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries, return true; } -/////////////////////////////////////////////// -// MemoryMappedFile - -MemoryMappedFile::MemoryMappedFile() - : file_(base::kInvalidPlatformFileValue), - data_(NULL), - length_(0) { -} - -bool MemoryMappedFile::MapFileToMemoryInternal() { - base::ThreadRestrictions::AssertIOAllowed(); - - struct stat file_stat; - if (fstat(file_, &file_stat) == base::kInvalidPlatformFileValue) { - DLOG(ERROR) << "Couldn't fstat " << file_ << ", errno " << errno; - return false; - } - length_ = file_stat.st_size; - - data_ = static_cast<uint8*>( - mmap(NULL, length_, PROT_READ, MAP_SHARED, file_, 0)); - if (data_ == MAP_FAILED) - DLOG(ERROR) << "Couldn't mmap " << file_ << ", errno " << errno; - - return data_ != MAP_FAILED; -} - -void MemoryMappedFile::CloseHandles() { - base::ThreadRestrictions::AssertIOAllowed(); - - if (data_ != NULL) - munmap(data_, length_); - if (file_ != base::kInvalidPlatformFileValue) - ignore_result(HANDLE_EINTR(close(file_))); - - data_ = NULL; - length_ = 0; - file_ = base::kInvalidPlatformFileValue; -} - bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info, const base::Time& cutoff_time) { return static_cast<time_t>(find_info.stat.st_mtime) >= cutoff_time.ToTimeT(); diff --git a/base/file_util_win.cc b/base/file_util_win.cc index 679b108..f7897a0 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -755,82 +755,6 @@ FilePath FileEnumerator::Next() { return FilePath(); } -/////////////////////////////////////////////// -// MemoryMappedFile - -MemoryMappedFile::MemoryMappedFile() - : file_(INVALID_HANDLE_VALUE), - file_mapping_(INVALID_HANDLE_VALUE), - data_(NULL), - length_(INVALID_FILE_SIZE) { -} - -bool MemoryMappedFile::InitializeAsImageSection(const FilePath& file_name) { - if (IsValid()) - return false; - file_ = base::CreatePlatformFile( - file_name, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, - NULL, NULL); - - if (file_ == base::kInvalidPlatformFileValue) { - DLOG(ERROR) << "Couldn't open " << file_name.value(); - return false; - } - - if (!MapFileToMemoryInternalEx(SEC_IMAGE)) { - CloseHandles(); - return false; - } - - return true; -} - -bool MemoryMappedFile::MapFileToMemoryInternal() { - return MapFileToMemoryInternalEx(0); -} - -bool MemoryMappedFile::MapFileToMemoryInternalEx(int flags) { - base::ThreadRestrictions::AssertIOAllowed(); - - if (file_ == INVALID_HANDLE_VALUE) - return false; - - length_ = ::GetFileSize(file_, NULL); - if (length_ == INVALID_FILE_SIZE) - return false; - - file_mapping_ = ::CreateFileMapping(file_, NULL, PAGE_READONLY | flags, - 0, 0, NULL); - if (!file_mapping_) { - // According to msdn, system error codes are only reserved up to 15999. - // http://msdn.microsoft.com/en-us/library/ms681381(v=VS.85).aspx. - UMA_HISTOGRAM_ENUMERATION("MemoryMappedFile.CreateFileMapping", - logging::GetLastSystemErrorCode(), 16000); - return false; - } - - data_ = static_cast<uint8*>( - ::MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, 0)); - if (!data_) { - UMA_HISTOGRAM_ENUMERATION("MemoryMappedFile.MapViewOfFile", - logging::GetLastSystemErrorCode(), 16000); - } - return data_ != NULL; -} - -void MemoryMappedFile::CloseHandles() { - if (data_) - ::UnmapViewOfFile(data_); - if (file_mapping_ != INVALID_HANDLE_VALUE) - ::CloseHandle(file_mapping_); - if (file_ != INVALID_HANDLE_VALUE) - ::CloseHandle(file_); - - data_ = NULL; - file_mapping_ = file_ = INVALID_HANDLE_VALUE; - length_ = INVALID_FILE_SIZE; -} - bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info, const base::Time& cutoff_time) { base::ThreadRestrictions::AssertIOAllowed(); diff --git a/base/files/memory_mapped_file.cc b/base/files/memory_mapped_file.cc new file mode 100644 index 0000000..9e98bc6 --- /dev/null +++ b/base/files/memory_mapped_file.cc @@ -0,0 +1,58 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/files/memory_mapped_file.h" + +#include "base/file_path.h" +#include "base/logging.h" + +namespace base { + +MemoryMappedFile::~MemoryMappedFile() { + CloseHandles(); +} + +bool MemoryMappedFile::Initialize(const FilePath& file_name) { + if (IsValid()) + return false; + + if (!MapFileToMemory(file_name)) { + CloseHandles(); + return false; + } + + return true; +} + +bool MemoryMappedFile::Initialize(PlatformFile file) { + if (IsValid()) + return false; + + file_ = file; + + if (!MapFileToMemoryInternal()) { + CloseHandles(); + return false; + } + + return true; +} + +bool MemoryMappedFile::IsValid() const { + return data_ != NULL; +} + +bool MemoryMappedFile::MapFileToMemory(const FilePath& file_name) { + file_ = CreatePlatformFile(file_name, PLATFORM_FILE_OPEN | PLATFORM_FILE_READ, + NULL, NULL); + + if (file_ == kInvalidPlatformFileValue) { + DLOG(ERROR) << "Couldn't open " << file_name.AsUTF8Unsafe(); + return false; + } + + return MapFileToMemoryInternal(); +} + +} // namespace base diff --git a/base/files/memory_mapped_file.h b/base/files/memory_mapped_file.h new file mode 100644 index 0000000..6df1bad --- /dev/null +++ b/base/files/memory_mapped_file.h @@ -0,0 +1,76 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_FILES_MEMORY_MAPPED_FILE_H_ +#define BASE_FILES_MEMORY_MAPPED_FILE_H_ + +#include "base/base_export.h" +#include "base/basictypes.h" +#include "base/platform_file.h" +#include "build/build_config.h" + +#if defined(OS_WIN) +#include <windows.h> +#endif + +namespace base { + +class FilePath; + +class BASE_EXPORT MemoryMappedFile { + public: + // The default constructor sets all members to invalid/null values. + MemoryMappedFile(); + ~MemoryMappedFile(); + + // Opens an existing file and maps it into memory. Access is restricted to + // read only. If this object already points to a valid memory mapped file + // then this method will fail and return false. If it cannot open the file, + // the file does not exist, or the memory mapping fails, it will return false. + // Later we may want to allow the user to specify access. + bool Initialize(const FilePath& file_name); + // As above, but works with an already-opened file. MemoryMappedFile will take + // ownership of |file| and close it when done. + bool Initialize(PlatformFile file); + +#if defined(OS_WIN) + // Opens an existing file and maps it as an image section. Please refer to + // the Initialize function above for additional information. + bool InitializeAsImageSection(const FilePath& file_name); +#endif // OS_WIN + + const uint8* data() const { return data_; } + size_t length() const { return length_; } + + // Is file_ a valid file handle that points to an open, memory mapped file? + bool IsValid() const; + + private: + // Open the given file and pass it to MapFileToMemoryInternal(). + bool MapFileToMemory(const FilePath& file_name); + + // Map the file to memory, set data_ to that memory address. Return true on + // success, false on any kind of failure. This is a helper for Initialize(). + bool MapFileToMemoryInternal(); + + // Closes all open handles. Later we may want to make this public. + void CloseHandles(); + +#if defined(OS_WIN) + // MapFileToMemoryInternal calls this function. It provides the ability to + // pass in flags which control the mapped section. + bool MapFileToMemoryInternalEx(int flags); + + HANDLE file_mapping_; +#endif + PlatformFile file_; + uint8* data_; + size_t length_; + + DISALLOW_COPY_AND_ASSIGN(MemoryMappedFile); +}; + +} // namespace base + +#endif // BASE_FILES_MEMORY_MAPPED_FILE_H_ diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc new file mode 100644 index 0000000..38b2716 --- /dev/null +++ b/base/files/memory_mapped_file_posix.cc @@ -0,0 +1,54 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/files/memory_mapped_file.h" + +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "base/logging.h" +#include "base/posix/eintr_wrapper.h" +#include "base/threading/thread_restrictions.h" + +namespace base { + +MemoryMappedFile::MemoryMappedFile() + : file_(kInvalidPlatformFileValue), + data_(NULL), + length_(0) { +} + +bool MemoryMappedFile::MapFileToMemoryInternal() { + ThreadRestrictions::AssertIOAllowed(); + + struct stat file_stat; + if (fstat(file_, &file_stat) == kInvalidPlatformFileValue) { + DLOG(ERROR) << "Couldn't fstat " << file_ << ", errno " << errno; + return false; + } + length_ = file_stat.st_size; + + data_ = static_cast<uint8*>( + mmap(NULL, length_, PROT_READ, MAP_SHARED, file_, 0)); + if (data_ == MAP_FAILED) + DLOG(ERROR) << "Couldn't mmap " << file_ << ", errno " << errno; + + return data_ != MAP_FAILED; +} + +void MemoryMappedFile::CloseHandles() { + ThreadRestrictions::AssertIOAllowed(); + + if (data_ != NULL) + munmap(data_, length_); + if (file_ != kInvalidPlatformFileValue) + ignore_result(HANDLE_EINTR(close(file_))); + + data_ = NULL; + length_ = 0; + file_ = kInvalidPlatformFileValue; +} + +} // namespace base diff --git a/base/files/memory_mapped_file_win.cc b/base/files/memory_mapped_file_win.cc new file mode 100644 index 0000000..1a24de2 --- /dev/null +++ b/base/files/memory_mapped_file_win.cc @@ -0,0 +1,87 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/files/memory_mapped_file.h" + +#include "base/file_path.h" +#include "base/logging.h" +#include "base/metrics/histogram.h" +#include "base/string16.h" +#include "base/threading/thread_restrictions.h" + +namespace base { + +MemoryMappedFile::MemoryMappedFile() + : file_(INVALID_HANDLE_VALUE), + file_mapping_(INVALID_HANDLE_VALUE), + data_(NULL), + length_(INVALID_FILE_SIZE) { +} + +bool MemoryMappedFile::InitializeAsImageSection(const FilePath& file_name) { + if (IsValid()) + return false; + file_ = CreatePlatformFile(file_name, PLATFORM_FILE_OPEN | PLATFORM_FILE_READ, + NULL, NULL); + + if (file_ == kInvalidPlatformFileValue) { + DLOG(ERROR) << "Couldn't open " << file_name.AsUTF8Unsafe(); + return false; + } + + if (!MapFileToMemoryInternalEx(SEC_IMAGE)) { + CloseHandles(); + return false; + } + + return true; +} + +bool MemoryMappedFile::MapFileToMemoryInternal() { + return MapFileToMemoryInternalEx(0); +} + +bool MemoryMappedFile::MapFileToMemoryInternalEx(int flags) { + ThreadRestrictions::AssertIOAllowed(); + + if (file_ == INVALID_HANDLE_VALUE) + return false; + + length_ = ::GetFileSize(file_, NULL); + if (length_ == INVALID_FILE_SIZE) + return false; + + file_mapping_ = ::CreateFileMapping(file_, NULL, PAGE_READONLY | flags, + 0, 0, NULL); + if (!file_mapping_) { + // According to msdn, system error codes are only reserved up to 15999. + // http://msdn.microsoft.com/en-us/library/ms681381(v=VS.85).aspx. + UMA_HISTOGRAM_ENUMERATION("MemoryMappedFile.CreateFileMapping", + logging::GetLastSystemErrorCode(), 16000); + return false; + } + + data_ = static_cast<uint8*>( + ::MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, 0)); + if (!data_) { + UMA_HISTOGRAM_ENUMERATION("MemoryMappedFile.MapViewOfFile", + logging::GetLastSystemErrorCode(), 16000); + } + return data_ != NULL; +} + +void MemoryMappedFile::CloseHandles() { + if (data_) + ::UnmapViewOfFile(data_); + if (file_mapping_ != INVALID_HANDLE_VALUE) + ::CloseHandle(file_mapping_); + if (file_ != INVALID_HANDLE_VALUE) + ::CloseHandle(file_); + + data_ = NULL; + file_mapping_ = file_ = INVALID_HANDLE_VALUE; + length_ = INVALID_FILE_SIZE; +} + +} // namespace base diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc index fed1176..42aa8ad 100644 --- a/base/i18n/icu_util.cc +++ b/base/i18n/icu_util.cc @@ -14,6 +14,7 @@ #include "base/file_util.h" #include "base/files/file_path.h" +#include "base/files/memory_mapped_file.h" #include "base/logging.h" #include "base/path_service.h" #include "base/string_util.h" @@ -111,7 +112,7 @@ bool Initialize() { // Chrome doesn't normally shut down ICU, so the mapped data shouldn't ever // be released. - static file_util::MemoryMappedFile mapped_file; + static base::MemoryMappedFile mapped_file; if (!mapped_file.IsValid()) { // Assume it is in the framework bundle's Resources directory. FilePath data_path = diff --git a/base/test/test_file_util_mac.cc b/base/test/test_file_util_mac.cc index b52b39c..3af2c10 100644 --- a/base/test/test_file_util_mac.cc +++ b/base/test/test_file_util_mac.cc @@ -6,8 +6,10 @@ #include <sys/mman.h> #include <errno.h> + #include "base/logging.h" #include "base/file_util.h" +#include "base/files/memory_mapped_file.h" namespace file_util { @@ -30,7 +32,7 @@ bool EvictFileFromSystemCache(const base::FilePath& file) { return true; } - file_util::MemoryMappedFile mapped_file; + base::MemoryMappedFile mapped_file; if (!mapped_file.Initialize(file)) { DLOG(WARNING) << "failed to memory map " << file.value(); return false; |