summaryrefslogtreecommitdiffstats
path: root/base/files
diff options
context:
space:
mode:
authortfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-24 21:55:45 +0000
committertfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-24 21:55:45 +0000
commitc3088cbb5cbd5c91b6c5602750ec327ff7963862 (patch)
tree4aac06d2b2541d9ef2744f719478f6c2c88b00c1 /base/files
parent47e870bf26f0c01dafe611ec03c0139c735063df (diff)
downloadchromium_src-c3088cbb5cbd5c91b6c5602750ec327ff7963862.zip
chromium_src-c3088cbb5cbd5c91b6c5602750ec327ff7963862.tar.gz
chromium_src-c3088cbb5cbd5c91b6c5602750ec327ff7963862.tar.bz2
base: Move MemoryMappedFile out of file_util.h and into its own header file.
BUG=175002 TEST=base_unittests R=brettw@chromium.org TBR=erikwright@chromium.org,tommi@chromium.org,fischman@chromium.org,ben@chromium.org Review URL: https://chromiumcodereview.appspot.com/12321062 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@184356 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/files')
-rw-r--r--base/files/memory_mapped_file.cc58
-rw-r--r--base/files/memory_mapped_file.h76
-rw-r--r--base/files/memory_mapped_file_posix.cc54
-rw-r--r--base/files/memory_mapped_file_win.cc87
4 files changed, 275 insertions, 0 deletions
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