MongoDB  2.7.0
mmap.h
1 // mmap.h
2 
3 /* Copyright 2009 10gen Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <set>
21 #include <sstream>
22 #include <vector>
23 
24 #include <boost/thread/xtime.hpp>
25 
26 #include "mongo/client/export_macros.h"
27 #include "mongo/util/concurrency/rwlock.h"
28 #include "mongo/util/goodies.h"
29 
30 namespace mongo {
31 
32  extern const size_t g_minOSPageSizeBytes;
33  void minOSPageSizeBytesTest(size_t minOSPageSizeBytes); // lame-o
34 
35  // call this if syncing data fails
36  void dataSyncFailedHandler();
37 
38  class MAdvise {
39  MONGO_DISALLOW_COPYING(MAdvise);
40  public:
41  enum Advice { Sequential=1 , Random=2 };
42  MAdvise(void *p, unsigned len, Advice a);
43  ~MAdvise(); // destructor resets the range to MADV_NORMAL
44  private:
45  void *_p;
46  unsigned _len;
47  };
48 
49  // lock order: lock dbMutex before this if you lock both
50  class MONGO_CLIENT_API LockMongoFilesShared {
51  friend class LockMongoFilesExclusive;
52  static RWLockRecursiveNongreedy mmmutex;
53  static unsigned era;
55  public:
56  LockMongoFilesShared() : lk(mmmutex) { }
57 
64  static unsigned getEra() { return era; }
65 
66  static void assertExclusivelyLocked() { mmmutex.assertExclusivelyLocked(); }
67  static void assertAtLeastReadLocked() { mmmutex.assertAtLeastReadLocked(); }
68  };
69 
70  class MONGO_CLIENT_API LockMongoFilesExclusive {
72  public:
73  LockMongoFilesExclusive() : lk(LockMongoFilesShared::mmmutex) {
74  LockMongoFilesShared::era++;
75  }
76  };
77 
78  /* the administrative-ish stuff here */
79  class MongoFile : boost::noncopyable {
80  public:
82  class Flushable {
83  public:
84  virtual ~Flushable() {}
85  virtual void flush() = 0;
86  };
87 
88  virtual ~MongoFile() {}
89 
90  enum Options {
91  SEQUENTIAL = 1, // hint - e.g. FILE_FLAG_SEQUENTIAL_SCAN on windows
92  READONLY = 2 // not contractually guaranteed, but if specified the impl has option to fault writes
93  };
94 
98  template < class F >
99  static void forEach( F fun );
100 
103  static std::set<MongoFile*>& getAllFiles();
104 
105  // callbacks if you need them
106  static void (*notifyPreFlush)();
107  static void (*notifyPostFlush)();
108 
109  static int flushAll( bool sync ); // returns n flushed
110  static long long totalMappedLength();
111  static void closeAllFiles( std::stringstream &message );
112 
113  virtual bool isDurableMappedFile() { return false; }
114 
115  string filename() const { return _filename; }
116  void setFilename(const std::string& fn);
117 
118  virtual uint64_t getUniqueId() const = 0;
119 
120  private:
121  string _filename;
122  static int _flushAll( bool sync ); // returns n flushed
123  protected:
124  virtual void close() = 0;
125  virtual void flush(bool sync) = 0;
130  virtual Flushable * prepareFlush() = 0;
131 
132  void created(); /* subclass must call after create */
133 
134  /* subclass must call in destructor (or at close).
135  removes this from pathToFile and other maps
136  safe to call more than once, albeit might be wasted work
137  ideal to call close to the close, if the close is well before object destruction
138  */
139  void destroyed();
140 
141  virtual unsigned long long length() const = 0;
142  };
143 
150  class MONGO_CLIENT_API MongoFileFinder : boost::noncopyable {
151  public:
155  MongoFile* findByPath(const std::string& path) const;
156 
157  private:
159  };
160 
161  class MemoryMappedFile : public MongoFile {
162  protected:
163  virtual void* viewForFlushing() {
164  if( views.size() == 0 )
165  return 0;
166  verify( views.size() == 1 );
167  return views[0];
168  }
169  public:
171 
172  virtual ~MemoryMappedFile() {
174  close();
175  }
176 
177  virtual void close();
178 
179  // Throws exception if file doesn't exist. (dm may2010: not sure if this is always true?)
180  void* map(const char *filename);
181 
184  void* mapWithOptions(const char *filename, int options);
185 
186  /* Creates with length if DNE, otherwise uses existing file length,
187  passed length.
188  @param options MongoFile::Options bits
189  */
190  void* map(const char *filename, unsigned long long &length, int options = 0 );
191 
192  /* Create. Must not exist.
193  @param zero fill file with zeros when true
194  */
195  void* create(const std::string& filename, unsigned long long len, bool zero);
196 
197  void flush(bool sync);
198  virtual Flushable * prepareFlush();
199 
200  long shortLength() const { return (long) len; }
201  unsigned long long length() const { return len; }
202  HANDLE getFd() const { return fd; }
206  void* createReadOnlyMap();
207  void* createPrivateMap();
208 
210  static void makeWritable(void *, unsigned len)
211 #if defined(_WIN32)
212  ;
213 #else
214  { }
215 #endif
216 
217  virtual uint64_t getUniqueId() const { return _uniqueId; }
218 
219  private:
220  static void updateLength( const char *filename, unsigned long long &length );
221 
222  HANDLE fd;
223  HANDLE maphandle;
224  std::vector<void *> views;
225  unsigned long long len;
226  const uint64_t _uniqueId;
227 #ifdef _WIN32
228  boost::shared_ptr<mutex> _flushMutex;
229  void clearWritableBits(void *privateView);
230  public:
231  static const unsigned ChunkSize = 64 * 1024 * 1024;
232  static const unsigned NChunks = 1024 * 1024;
233 #else
234  void clearWritableBits(void *privateView) { }
235 #endif
236 
237  protected:
238 
240  void* remapPrivateView(void *oldPrivateAddr);
241  };
242 
244  template < class F >
245  inline void MongoFile::forEach( F p ) {
247  const std::set<MongoFile*>& mmfiles = MongoFile::getAllFiles();
248  for ( std::set<MongoFile*>::const_iterator i = mmfiles.begin(); i != mmfiles.end(); i++ )
249  p(*i);
250  }
251 
252 #if defined(_WIN32)
253  class ourbitset {
254  volatile unsigned bits[MemoryMappedFile::NChunks]; // volatile as we are doing double check locking
255  public:
256  ourbitset() {
257  memset((void*) bits, 0, sizeof(bits));
258  }
259  bool get(unsigned i) const {
260  unsigned x = i / 32;
261  verify( x < MemoryMappedFile::NChunks );
262  return (bits[x] & (1 << (i%32))) != 0;
263  }
264  void set(unsigned i) {
265  unsigned x = i / 32;
266  wassert( x < (MemoryMappedFile::NChunks*2/3) ); // warn if getting close to limit
267  verify( x < MemoryMappedFile::NChunks );
268  bits[x] |= (1 << (i%32));
269  }
270  void clear(unsigned i) {
271  unsigned x = i / 32;
272  verify( x < MemoryMappedFile::NChunks );
273  bits[x] &= ~(1 << (i%32));
274  }
275  };
276  extern ourbitset writable;
277  void makeChunkWritable(size_t chunkno);
278  inline void MemoryMappedFile::makeWritable(void *_p, unsigned len) {
279  size_t p = (size_t) _p;
280  unsigned a = p/ChunkSize;
281  unsigned b = (p+len)/ChunkSize;
282  for( unsigned i = a; i <= b; i++ ) {
283  if( !writable.get(i) ) {
284  makeChunkWritable(i);
285  }
286  }
287  }
288 
289 #endif
290 
291 } // namespace mongo
void * remapPrivateView(void *oldPrivateAddr)
close the current private view and open a new replacement
Definition: mmap_posix.cpp:221
Definition: mmap.h:79
static void makeWritable(void *, unsigned len)
make the private map range writable (necessary for our windows implementation)
Definition: mmap.h:210
Definition: rwlock.h:210
virtual Flushable * prepareFlush()=0
returns a thread safe object that you can call flush on Flushable has to fail nicely if the underlyin...
Definition: rwlock.h:239
Definition: mmap.h:161
virtual Flushable * prepareFlush()
returns a thread safe object that you can call flush on Flushable has to fail nicely if the underlyin...
Definition: mmap_posix.cpp:292
look up a MMF by filename.
Definition: mmap.h:150
Definition: rwlock.h:190
Definition: mmap.h:70
static unsigned getEra()
era changes anytime memory maps come and go.
Definition: mmap.h:64
void * createReadOnlyMap()
create a new view with the specified properties.
Definition: mmap_posix.cpp:186
Definition: mmap.h:38
Definition: mmap.h:50
Flushable has to fail nicely if the underlying object gets killed.
Definition: mmap.h:82
void * mapWithOptions(const char *filename, int options)
Definition: mmap.cpp:78
static std::set< MongoFile * > & getAllFiles()
note: you need to be in mmmutex when using this.
Definition: mmap.cpp:96
static void forEach(F fun)
p is called from within a mutex that MongoFile uses.
Definition: mmap.h:245