summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/mmap_v1/mmap.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/storage/mmap_v1/mmap.h')
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap.h392
1 files changed, 208 insertions, 184 deletions
diff --git a/src/mongo/db/storage/mmap_v1/mmap.h b/src/mongo/db/storage/mmap_v1/mmap.h
index f70b64c96eb..ae9a0796a4b 100644
--- a/src/mongo/db/storage/mmap_v1/mmap.h
+++ b/src/mongo/db/storage/mmap_v1/mmap.h
@@ -38,225 +38,249 @@
namespace mongo {
#if !defined(_WIN32)
- typedef int HANDLE;
+typedef int HANDLE;
#endif
- extern const size_t g_minOSPageSizeBytes;
- void minOSPageSizeBytesTest(size_t minOSPageSizeBytes); // lame-o
+extern const size_t g_minOSPageSizeBytes;
+void minOSPageSizeBytesTest(size_t minOSPageSizeBytes); // lame-o
- // call this if syncing data fails
- void dataSyncFailedHandler();
+// call this if syncing data fails
+void dataSyncFailedHandler();
- class MAdvise {
- MONGO_DISALLOW_COPYING(MAdvise);
- public:
- enum Advice { Sequential=1 , Random=2 };
- MAdvise(void *p, unsigned len, Advice a);
- ~MAdvise(); // destructor resets the range to MADV_NORMAL
- private:
- void *_p;
- unsigned _len;
- };
+class MAdvise {
+ MONGO_DISALLOW_COPYING(MAdvise);
- // lock order: lock dbMutex before this if you lock both
- class LockMongoFilesShared {
- friend class LockMongoFilesExclusive;
- static RWLockRecursiveNongreedy mmmutex;
- static unsigned era;
- RWLockRecursive::Shared lk;
- public:
- LockMongoFilesShared() : lk(mmmutex) { }
+public:
+ enum Advice { Sequential = 1, Random = 2 };
+ MAdvise(void* p, unsigned len, Advice a);
+ ~MAdvise(); // destructor resets the range to MADV_NORMAL
+private:
+ void* _p;
+ unsigned _len;
+};
- /** era changes anytime memory maps come and go. thus you can use this as a cheap way to check
- if nothing has changed since the last time you locked. Of course you must be shared locked
- at the time of this call, otherwise someone could be in progress.
+// lock order: lock dbMutex before this if you lock both
+class LockMongoFilesShared {
+ friend class LockMongoFilesExclusive;
+ static RWLockRecursiveNongreedy mmmutex;
+ static unsigned era;
+ RWLockRecursive::Shared lk;
- This is used for yielding; see PageFaultException::touch().
- */
- static unsigned getEra() { return era; }
+public:
+ LockMongoFilesShared() : lk(mmmutex) {}
- static void assertExclusivelyLocked() { mmmutex.assertExclusivelyLocked(); }
- static void assertAtLeastReadLocked() { mmmutex.assertAtLeastReadLocked(); }
- };
+ /** era changes anytime memory maps come and go. thus you can use this as a cheap way to check
+ if nothing has changed since the last time you locked. Of course you must be shared locked
+ at the time of this call, otherwise someone could be in progress.
+
+ This is used for yielding; see PageFaultException::touch().
+ */
+ static unsigned getEra() {
+ return era;
+ }
+
+ static void assertExclusivelyLocked() {
+ mmmutex.assertExclusivelyLocked();
+ }
+ static void assertAtLeastReadLocked() {
+ mmmutex.assertAtLeastReadLocked();
+ }
+};
+
+class LockMongoFilesExclusive {
+ RWLockRecursive::Exclusive lk;
- class LockMongoFilesExclusive {
- RWLockRecursive::Exclusive lk;
+public:
+ LockMongoFilesExclusive() : lk(LockMongoFilesShared::mmmutex) {
+ LockMongoFilesShared::era++;
+ }
+};
+
+/* the administrative-ish stuff here */
+class MongoFile {
+ MONGO_DISALLOW_COPYING(MongoFile);
+
+public:
+ /** Flushable has to fail nicely if the underlying object gets killed */
+ class Flushable {
public:
- LockMongoFilesExclusive() : lk(LockMongoFilesShared::mmmutex) {
- LockMongoFilesShared::era++;
- }
+ virtual ~Flushable() {}
+ virtual void flush() = 0;
};
- /* the administrative-ish stuff here */
- class MongoFile {
- MONGO_DISALLOW_COPYING(MongoFile);
- public:
- /** Flushable has to fail nicely if the underlying object gets killed */
- class Flushable {
- public:
- virtual ~Flushable() {}
- virtual void flush() = 0;
- };
-
- MongoFile() {}
- virtual ~MongoFile() {}
-
- enum Options {
- SEQUENTIAL = 1, // hint - e.g. FILE_FLAG_SEQUENTIAL_SCAN on windows
- READONLY = 2 // not contractually guaranteed, but if specified the impl has option to fault writes
- };
-
- /** @param fun is called for each MongoFile.
- called from within a mutex that MongoFile uses. so be careful not to deadlock.
- */
- template < class F >
- static void forEach( F fun );
+ MongoFile() {}
+ virtual ~MongoFile() {}
- /** note: you need to be in mmmutex when using this. forEach (above) handles that for you automatically.
-*/
- static std::set<MongoFile*>& getAllFiles();
+ enum Options {
+ SEQUENTIAL = 1, // hint - e.g. FILE_FLAG_SEQUENTIAL_SCAN on windows
+ READONLY =
+ 2 // not contractually guaranteed, but if specified the impl has option to fault writes
+ };
- // callbacks if you need them
- static void (*notifyPreFlush)();
- static void (*notifyPostFlush)();
+ /** @param fun is called for each MongoFile.
+ called from within a mutex that MongoFile uses. so be careful not to deadlock.
+ */
+ template <class F>
+ static void forEach(F fun);
- static int flushAll( bool sync ); // returns n flushed
- static long long totalMappedLength();
- static void closeAllFiles( std::stringstream &message );
+ /** note: you need to be in mmmutex when using this. forEach (above) handles that for you automatically.
+*/
+ static std::set<MongoFile*>& getAllFiles();
- virtual bool isDurableMappedFile() { return false; }
+ // callbacks if you need them
+ static void (*notifyPreFlush)();
+ static void (*notifyPostFlush)();
- std::string filename() const { return _filename; }
- void setFilename(const std::string& fn);
+ static int flushAll(bool sync); // returns n flushed
+ static long long totalMappedLength();
+ static void closeAllFiles(std::stringstream& message);
- virtual uint64_t getUniqueId() const = 0;
+ virtual bool isDurableMappedFile() {
+ return false;
+ }
- private:
- std::string _filename;
- static int _flushAll( bool sync ); // returns n flushed
- protected:
- virtual void close() = 0;
- virtual void flush(bool sync) = 0;
- /**
- * returns a thread safe object that you can call flush on
- * Flushable has to fail nicely if the underlying object gets killed
- */
- virtual Flushable * prepareFlush() = 0;
+ std::string filename() const {
+ return _filename;
+ }
+ void setFilename(const std::string& fn);
+
+ virtual uint64_t getUniqueId() const = 0;
+
+private:
+ std::string _filename;
+ static int _flushAll(bool sync); // returns n flushed
+protected:
+ virtual void close() = 0;
+ virtual void flush(bool sync) = 0;
+ /**
+ * returns a thread safe object that you can call flush on
+ * Flushable has to fail nicely if the underlying object gets killed
+ */
+ virtual Flushable* prepareFlush() = 0;
+
+ void created(); /* subclass must call after create */
+
+ /* subclass must call in destructor (or at close).
+ removes this from pathToFile and other maps
+ safe to call more than once, albeit might be wasted work
+ ideal to call close to the close, if the close is well before object destruction
+ */
+ void destroyed();
- void created(); /* subclass must call after create */
+ virtual unsigned long long length() const = 0;
+};
- /* subclass must call in destructor (or at close).
- removes this from pathToFile and other maps
- safe to call more than once, albeit might be wasted work
- ideal to call close to the close, if the close is well before object destruction
- */
- void destroyed();
+/** look up a MMF by filename. scoped mutex locking convention.
+ example:
+ MMFFinderByName finder;
+ DurableMappedFile *a = finder.find("file_name_a");
+ DurableMappedFile *b = finder.find("file_name_b");
+*/
+class MongoFileFinder {
+ MONGO_DISALLOW_COPYING(MongoFileFinder);
- virtual unsigned long long length() const = 0;
- };
+public:
+ MongoFileFinder() {}
- /** look up a MMF by filename. scoped mutex locking convention.
- example:
- MMFFinderByName finder;
- DurableMappedFile *a = finder.find("file_name_a");
- DurableMappedFile *b = finder.find("file_name_b");
+ /** @return The MongoFile object associated with the specified file name. If no file is open
+ with the specified name, returns null.
*/
- class MongoFileFinder {
- MONGO_DISALLOW_COPYING(MongoFileFinder);
- public:
- MongoFileFinder() { }
+ MongoFile* findByPath(const std::string& path) const;
+
+private:
+ LockMongoFilesShared _lk;
+};
+
+class MemoryMappedFile : public MongoFile {
+protected:
+ virtual void* viewForFlushing() {
+ if (views.size() == 0)
+ return 0;
+ verify(views.size() == 1);
+ return views[0];
+ }
- /** @return The MongoFile object associated with the specified file name. If no file is open
- with the specified name, returns null.
- */
- MongoFile* findByPath(const std::string& path) const;
+public:
+ MemoryMappedFile();
- private:
- LockMongoFilesShared _lk;
- };
+ virtual ~MemoryMappedFile() {
+ LockMongoFilesExclusive lk;
+ close();
+ }
- class MemoryMappedFile : public MongoFile {
- protected:
- virtual void* viewForFlushing() {
- if( views.size() == 0 )
- return 0;
- verify( views.size() == 1 );
- return views[0];
- }
- public:
- MemoryMappedFile();
+ virtual void close();
- virtual ~MemoryMappedFile() {
- LockMongoFilesExclusive lk;
- close();
- }
+ // Throws exception if file doesn't exist. (dm may2010: not sure if this is always true?)
+ void* map(const char* filename);
- virtual void close();
+ /** @param options see MongoFile::Options
+ */
+ void* mapWithOptions(const char* filename, int options);
- // Throws exception if file doesn't exist. (dm may2010: not sure if this is always true?)
- void* map(const char *filename);
+ /* Creates with length if DNE, otherwise uses existing file length,
+ passed length.
+ @param options MongoFile::Options bits
+ */
+ void* map(const char* filename, unsigned long long& length, int options = 0);
- /** @param options see MongoFile::Options
- */
- void* mapWithOptions(const char *filename, int options);
+ /* Create. Must not exist.
+ @param zero fill file with zeros when true
+ */
+ void* create(const std::string& filename, unsigned long long len, bool zero);
- /* Creates with length if DNE, otherwise uses existing file length,
- passed length.
- @param options MongoFile::Options bits
- */
- void* map(const char *filename, unsigned long long &length, int options = 0 );
+ void flush(bool sync);
+ virtual Flushable* prepareFlush();
- /* Create. Must not exist.
- @param zero fill file with zeros when true
+ long shortLength() const {
+ return (long)len;
+ }
+ unsigned long long length() const {
+ return len;
+ }
+ HANDLE getFd() const {
+ return fd;
+ }
+ /** create a new view with the specified properties.
+ automatically cleaned up upon close/destruction of the MemoryMappedFile object.
*/
- void* create(const std::string& filename, unsigned long long len, bool zero);
-
- void flush(bool sync);
- virtual Flushable * prepareFlush();
-
- long shortLength() const { return (long) len; }
- unsigned long long length() const { return len; }
- HANDLE getFd() const { return fd; }
- /** create a new view with the specified properties.
- automatically cleaned up upon close/destruction of the MemoryMappedFile object.
- */
- void* createReadOnlyMap();
- void* createPrivateMap();
-
- virtual uint64_t getUniqueId() const { return _uniqueId; }
-
- private:
- static void updateLength( const char *filename, unsigned long long &length );
-
- HANDLE fd;
- HANDLE maphandle;
- std::vector<void *> views;
- unsigned long long len;
- const uint64_t _uniqueId;
-#ifdef _WIN32
- // flush Mutex
- //
- // Protects:
- // Prevent flush() and close() from concurrently running.
- // It ensures close() cannot complete while flush() is running
- // Lock Ordering:
- // LockMongoFilesShared must be taken before _flushMutex if both are taken
- stdx::mutex _flushMutex;
-#endif
+ void* createReadOnlyMap();
+ void* createPrivateMap();
- protected:
+ virtual uint64_t getUniqueId() const {
+ return _uniqueId;
+ }
- /** close the current private view and open a new replacement */
- void* remapPrivateView(void *oldPrivateAddr);
- };
+private:
+ static void updateLength(const char* filename, unsigned long long& length);
- /** p is called from within a mutex that MongoFile uses. so be careful not to deadlock. */
- template < class F >
- inline void MongoFile::forEach( F p ) {
- LockMongoFilesShared lklk;
- const std::set<MongoFile*>& mmfiles = MongoFile::getAllFiles();
- for ( std::set<MongoFile*>::const_iterator i = mmfiles.begin(); i != mmfiles.end(); i++ )
- p(*i);
- }
+ HANDLE fd;
+ HANDLE maphandle;
+ std::vector<void*> views;
+ unsigned long long len;
+ const uint64_t _uniqueId;
+#ifdef _WIN32
+ // flush Mutex
+ //
+ // Protects:
+ // Prevent flush() and close() from concurrently running.
+ // It ensures close() cannot complete while flush() is running
+ // Lock Ordering:
+ // LockMongoFilesShared must be taken before _flushMutex if both are taken
+ stdx::mutex _flushMutex;
+#endif
-} // namespace mongo
+protected:
+ /** close the current private view and open a new replacement */
+ void* remapPrivateView(void* oldPrivateAddr);
+};
+
+/** p is called from within a mutex that MongoFile uses. so be careful not to deadlock. */
+template <class F>
+inline void MongoFile::forEach(F p) {
+ LockMongoFilesShared lklk;
+ const std::set<MongoFile*>& mmfiles = MongoFile::getAllFiles();
+ for (std::set<MongoFile*>::const_iterator i = mmfiles.begin(); i != mmfiles.end(); i++)
+ p(*i);
+}
+
+} // namespace mongo