diff options
-rwxr-xr-x | dbtests/mmaptests.cpp | 7 | ||||
-rw-r--r-- | dbtests/test.vcxproj | 1 | ||||
-rwxr-xr-x | dbtests/test.vcxproj.filters | 3 | ||||
-rw-r--r-- | util/file_allocator.cpp | 2 | ||||
-rw-r--r-- | util/mmap.cpp | 11 | ||||
-rw-r--r-- | util/mmap.h | 31 | ||||
-rw-r--r-- | util/mmap_win.cpp | 12 |
7 files changed, 58 insertions, 9 deletions
diff --git a/dbtests/mmaptests.cpp b/dbtests/mmaptests.cpp index a4deb9b8515..e83bf45d599 100755 --- a/dbtests/mmaptests.cpp +++ b/dbtests/mmaptests.cpp @@ -52,6 +52,13 @@ namespace MMapTests { char *w = (char *) f.view_write(); strcpy(w + 6, "world"); } + MongoFileFinder ff; + ASSERT( ff.findByPath(fn) ); + ASSERT( ff.findByPath("asdf") == 0 ); + } + { + MongoFileFinder ff; + ASSERT( ff.findByPath(fn) == 0 ); } int N = 10000; diff --git a/dbtests/test.vcxproj b/dbtests/test.vcxproj index 571201ddb10..f9d74755cd7 100644 --- a/dbtests/test.vcxproj +++ b/dbtests/test.vcxproj @@ -583,6 +583,7 @@ <ClCompile Include="..\util\concurrency\task.cpp" />
<ClCompile Include="..\util\concurrency\thread_pool.cpp" />
<ClCompile Include="..\util\concurrency\vars.cpp" />
+ <ClCompile Include="..\util\file_allocator.cpp" />
<ClCompile Include="..\util\log.cpp" />
<ClCompile Include="..\util\logfile.cpp" />
<ClCompile Include="..\util\mmap_win.cpp" />
diff --git a/dbtests/test.vcxproj.filters b/dbtests/test.vcxproj.filters index ea0ec85b834..c52f7f64359 100755 --- a/dbtests/test.vcxproj.filters +++ b/dbtests/test.vcxproj.filters @@ -764,6 +764,9 @@ <ClCompile Include="..\db\security_key.cpp">
<Filter>db\cpp</Filter>
</ClCompile>
+ <ClCompile Include="..\util\file_allocator.cpp">
+ <Filter>util\cpp</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\SConstruct">
diff --git a/util/file_allocator.cpp b/util/file_allocator.cpp index b951f83cb0d..ca4d7549aed 100644 --- a/util/file_allocator.cpp +++ b/util/file_allocator.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "../pch.h" +#include "pch.h" #include <fcntl.h> #include <errno.h> diff --git a/util/mmap.cpp b/util/mmap.cpp index 64c3106a78a..c14ad2bad67 100644 --- a/util/mmap.cpp +++ b/util/mmap.cpp @@ -23,6 +23,7 @@ namespace mongo { set<MongoFile*> MongoFile::mmfiles; + map<string,MongoFile*> MongoFile::pathToFile; /* Create. Must not exist. @param zero fill file with zeros when true @@ -77,6 +78,7 @@ namespace mongo { void MongoFile::destroyed() { rwlock lk( mmmutex , true ); mmfiles.erase(this); + pathToFile.erase( filename() ); } /*static*/ @@ -166,6 +168,15 @@ namespace mongo { rwlock lk( mmmutex , true ); mmfiles.insert(this); } + + void MongoFile::setFilename(string fn) { + rwlock( mmmutex, true ); + assert( _filename.empty() ); + _filename = fn; + MongoFile *&ptf = pathToFile[fn]; + massert(10000, "MongoFile : multiple opens of same filename", ptf == 0); + ptf = this; + } #if defined(_DEBUG) && !defined(_TESTINTENT) diff --git a/util/mmap.h b/util/mmap.h index 0d3eccc1ffc..0f4fd75bfee 100644 --- a/util/mmap.h +++ b/util/mmap.h @@ -44,6 +44,7 @@ namespace mongo { template < class F > static void forEach( F fun ); + /** note: you need to be in mmmutex when using this. forEach (above) handles that for you automatically. */ static set<MongoFile*>& getAllFiles() { return mmfiles; } // callbacks if you need them @@ -62,7 +63,11 @@ namespace mongo { virtual bool isMongoMMF() { return false; } + string filename() const { return _filename; } + void setFilename(string fn); + private: + string _filename; static int _flushAll( bool sync ); // returns n flushed protected: virtual void close() = 0; @@ -83,6 +88,8 @@ namespace mongo { virtual void _unlock() {} static set<MongoFile*> mmfiles; + public: + static map<string,MongoFile*> pathToFile; static RWLock mmmutex; }; @@ -92,6 +99,28 @@ namespace mongo { inline void MongoFile::unmarkAllWritable() {} #endif + /** look up a MMF by filename. scoped mutex locking convention. + example: + MMFFinderByName finder; + MongoMMF *a = finder.find("file_name_a"); + MongoMMF *b = finder.find("file_name_b"); + */ + class MongoFileFinder : boost::noncopyable { + public: + MongoFileFinder() : _lk(MongoFile::mmmutex,false) { } + + /** @return The MongoFile object associated with the specified file name. If no file is open + with the specified name, returns null. + */ + MongoFile* findByPath(string path) { + map<string,MongoFile*>::iterator i = MongoFile::pathToFile.find(path); + return i == MongoFile::pathToFile.end() ? 0 : i->second; + } + + private: + rwlock _lk; + }; + struct MongoFileAllowWrites { MongoFileAllowWrites(){ MongoFile::markAllWritable(); @@ -132,7 +161,6 @@ namespace mongo { long shortLength() const { return (long) len; } unsigned long long length() const { return len; } - string filename() const { return _filename; } /** create a new view with the specified properties. automatically cleaned up upon close/destruction of the MemoryMappedFile object. @@ -147,7 +175,6 @@ namespace mongo { HANDLE maphandle; vector<void *> views; unsigned long long len; - string _filename; #ifdef _WIN32 boost::shared_ptr<mutex> _flushMutex; diff --git a/util/mmap_win.cpp b/util/mmap_win.cpp index d7b17fc78a9..6b75a46ffce 100644 --- a/util/mmap_win.cpp +++ b/util/mmap_win.cpp @@ -23,7 +23,7 @@ namespace mongo { MemoryMappedFile::MemoryMappedFile() - : _flushMutex(new mutex("flushMutex")), _filename("??") + : _flushMutex(new mutex("flushMutex")) { fd = 0; maphandle = 0; @@ -64,7 +64,7 @@ namespace mongo { void *p = MapViewOfFile(maphandle, FILE_MAP_COPY, /*f ofs hi*/0, /*f ofs lo*/ 0, /*dwNumberOfBytesToMap 0 means to eof*/0); if ( p == 0 ) { DWORD e = GetLastError(); - log() << "FILE_MAP_COPY MapViewOfFile failed " << _filename << " " << errnoWithDescription(e) << endl; + log() << "FILE_MAP_COPY MapViewOfFile failed " << filename() << " " << errnoWithDescription(e) << endl; } else { views.push_back(p); @@ -77,7 +77,7 @@ namespace mongo { void *p = MapViewOfFile(maphandle, FILE_MAP_READ, /*f ofs hi*/0, /*f ofs lo*/ 0, /*dwNumberOfBytesToMap 0 means to eof*/0); if ( p == 0 ) { DWORD e = GetLastError(); - log() << "FILE_MAP_READ MapViewOfFile failed " << _filename << " " << errnoWithDescription(e) << endl; + log() << "FILE_MAP_READ MapViewOfFile failed " << filename() << " " << errnoWithDescription(e) << endl; } else { views.push_back(p); @@ -86,7 +86,7 @@ namespace mongo { } void* MemoryMappedFile::map(const char *filenameIn, unsigned long long &length, int options) { - _filename = filenameIn; + setFilename(filenameIn); /* big hack here: Babble uses db names with colons. doesn't seem to work on windows. temporary perhaps. */ char filename[256]; strncpy(filename, filenameIn, 255); @@ -209,13 +209,13 @@ namespace mongo { void MemoryMappedFile::flush(bool sync) { uassert(13056, "Async flushing not supported on windows", sync); if( !views.empty() ) { - WindowsFlushable f( views[0] , fd , _filename , _flushMutex); + WindowsFlushable f( views[0] , fd , filename() , _flushMutex); f.flush(); } } MemoryMappedFile::Flushable * MemoryMappedFile::prepareFlush() { - return new WindowsFlushable( views.empty() ? 0 : views[0] , fd , _filename , _flushMutex ); + return new WindowsFlushable( views.empty() ? 0 : views[0] , fd , filename() , _flushMutex ); } void MemoryMappedFile::_lock() {} void MemoryMappedFile::_unlock() {} |