• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_FILES_MEMORY_MAPPED_FILE_H_
6 #define BASE_FILES_MEMORY_MAPPED_FILE_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "base/base_export.h"
12 #include "base/files/file.h"
13 #include "base/macros.h"
14 #include "build/build_config.h"
15 
16 #if defined(OS_WIN)
17 #include <windows.h>
18 #endif
19 
20 namespace base {
21 
22 class FilePath;
23 
24 class BASE_EXPORT MemoryMappedFile {
25  public:
26   enum Access {
27     // Mapping a file into memory effectively allows for file I/O on any thread.
28     // The accessing thread could be paused while data from the file is paged
29     // into memory. Worse, a corrupted filesystem could cause a SEGV within the
30     // program instead of just an I/O error.
31     READ_ONLY,
32 
33     // This provides read/write access to a file and must be used with care of
34     // the additional subtleties involved in doing so. Though the OS will do
35     // the writing of data on its own time, too many dirty pages can cause
36     // the OS to pause the thread while it writes them out. The pause can
37     // be as much as 1s on some systems.
38     READ_WRITE,
39 
40     // This provides read/write access but with the ability to write beyond
41     // the end of the existing file up to a maximum size specified as the
42     // "region". Depending on the OS, the file may or may not be immediately
43     // extended to the maximum size though it won't be loaded in RAM until
44     // needed. Note, however, that the maximum size will still be reserved
45     // in the process address space.
46     READ_WRITE_EXTEND,
47   };
48 
49   // The default constructor sets all members to invalid/null values.
50   MemoryMappedFile();
51   ~MemoryMappedFile();
52 
53   // Used to hold information about a region [offset + size] of a file.
54   struct BASE_EXPORT Region {
55     static const Region kWholeFile;
56 
57     bool operator==(const Region& other) const;
58     bool operator!=(const Region& other) const;
59 
60     // Start of the region (measured in bytes from the beginning of the file).
61     int64_t offset;
62 
63     // Length of the region in bytes.
64     size_t size;
65   };
66 
67   // Opens an existing file and maps it into memory. |access| can be read-only
68   // or read/write but not read/write+extend. If this object already points
69   // to a valid memory mapped file then this method will fail and return
70   // false. If it cannot open the file, the file does not exist, or the
71   // memory mapping fails, it will return false.
72   bool Initialize(const FilePath& file_name, Access access);
Initialize(const FilePath & file_name)73   bool Initialize(const FilePath& file_name) {
74     return Initialize(file_name, READ_ONLY);
75   }
76 
77   // As above, but works with an already-opened file. |access| can be read-only
78   // or read/write but not read/write+extend. MemoryMappedFile takes ownership
79   // of |file| and closes it when done. |file| must have been opened with
80   // permissions suitable for |access|. If the memory mapping fails, it will
81   // return false.
82   bool Initialize(File file, Access access);
Initialize(File file)83   bool Initialize(File file) {
84     return Initialize(std::move(file), READ_ONLY);
85   }
86 
87   // As above, but works with a region of an already-opened file. All forms of
88   // |access| are allowed. If READ_WRITE_EXTEND is specified then |region|
89   // provides the maximum size of the file. If the memory mapping fails, it
90   // return false.
91   bool Initialize(File file, const Region& region, Access access);
Initialize(File file,const Region & region)92   bool Initialize(File file, const Region& region) {
93     return Initialize(std::move(file), region, READ_ONLY);
94   }
95 
data()96   const uint8_t* data() const { return data_; }
data()97   uint8_t* data() { return data_; }
length()98   size_t length() const { return length_; }
99 
100   // Is file_ a valid file handle that points to an open, memory mapped file?
101   bool IsValid() const;
102 
103  private:
104   // Given the arbitrarily aligned memory region [start, size], returns the
105   // boundaries of the region aligned to the granularity specified by the OS,
106   // (a page on Linux, ~32k on Windows) as follows:
107   // - |aligned_start| is page aligned and <= |start|.
108   // - |aligned_size| is a multiple of the VM granularity and >= |size|.
109   // - |offset| is the displacement of |start| w.r.t |aligned_start|.
110   static void CalculateVMAlignedBoundaries(int64_t start,
111                                            size_t size,
112                                            int64_t* aligned_start,
113                                            size_t* aligned_size,
114                                            int32_t* offset);
115 
116   // Map the file to memory, set data_ to that memory address. Return true on
117   // success, false on any kind of failure. This is a helper for Initialize().
118   bool MapFileRegionToMemory(const Region& region, Access access);
119 
120   // Closes all open handles.
121   void CloseHandles();
122 
123   File file_;
124   uint8_t* data_;
125   size_t length_;
126 
127 #if defined(OS_WIN)
128   win::ScopedHandle file_mapping_;
129 #endif
130 
131   DISALLOW_COPY_AND_ASSIGN(MemoryMappedFile);
132 };
133 
134 }  // namespace base
135 
136 #endif  // BASE_FILES_MEMORY_MAPPED_FILE_H_
137