bool DurableMappedFile::finishOpening() { LOG(3) << "mmf finishOpening " << (void*) _view_write << ' ' << filename() << " len:" << length(); if( _view_write ) { if (storageGlobalParams.dur) { scoped_lock lk2(privateViews._mutex()); _view_private = createPrivateMap(); if( _view_private == 0 ) { msgasserted(13636, str::stream() << "file " << filename() << " open/create failed in createPrivateMap (look in log for more information)"); } privateViews.add_inlock(_view_private, this); // note that testIntent builds use this, even though it points to view_write then... } else { _view_private = _view_write; } return true; } return false; }
DurableMappedFile::~DurableMappedFile() { try { LOG(3) << "mmf close " << filename(); // Notify the durability system that we are closing a file. getDur().closingFileNotification(); LockMongoFilesExclusive lk; privateViews.remove(_view_private, length()); _view_write = _view_private = 0; MemoryMappedFile::close(); } catch (...) { error() << "exception in ~DurableMappedFile"; } }
DurableMappedFile::~DurableMappedFile() { try { LOG(3) << "mmf close " << filename() << endl; // Only notifiy the durability system if the file was actually opened if (view_write()) { dur::closingFileNotification(); } LockMongoFilesExclusive lk; privateViews.remove(_view_private); _view_write = _view_private = 0; MemoryMappedFile::close(); } catch(...) { error() << "exception in ~DurableMappedFile" << endl; } }
DurableMappedFile::~DurableMappedFile() { try { LOG(3) << "mmf close " << filename(); // If _view_private was not set, this means file open failed if (_view_private) { // Notify the durability system that we are closing a file so it can ensure we // will not have journaled operations with no corresponding file. getDur().closingFileNotification(); } LockMongoFilesExclusive lk; privateViews.remove(_view_private, length()); MemoryMappedFile::close(); } catch (...) { error() << "exception in ~DurableMappedFile"; } }
namespace mongo { void DurableMappedFile::remapThePrivateView() { verify(storageGlobalParams.dur); _willNeedRemap = false; // todo 1.9 : it turns out we require that we always remap to the same address. // so the remove / add isn't necessary and can be removed? void *old = _view_private; //privateViews.remove(_view_private); _view_private = remapPrivateView(_view_private); //privateViews.add(_view_private, this); fassert( 16112, _view_private == old ); } /** register view. threadsafe */ void PointerToDurableMappedFile::add(void *view, DurableMappedFile *f) { verify(view); verify(f); mutex::scoped_lock lk(_m); _views.insert( pair<void*,DurableMappedFile*>(view,f) ); } /** de-register view. threadsafe */ void PointerToDurableMappedFile::remove(void *view) { if( view ) { mutex::scoped_lock lk(_m); _views.erase(view); } } PointerToDurableMappedFile::PointerToDurableMappedFile() : _m("PointerToDurableMappedFile") { #if defined(SIZE_MAX) size_t max = SIZE_MAX; #else size_t max = ~((size_t)0); #endif verify( max > (size_t) this ); // just checking that no one redef'd SIZE_MAX and that it is sane // this way we don't need any boundary checking in _find() _views.insert( pair<void*,DurableMappedFile*>((void*)0,(DurableMappedFile*)0) ); _views.insert( pair<void*,DurableMappedFile*>((void*)max,(DurableMappedFile*)0) ); } /** underscore version of find is for when you are already locked @param ofs out return our offset in the view @return the DurableMappedFile to which this pointer belongs */ DurableMappedFile* PointerToDurableMappedFile::find_inlock(void *p, /*out*/ size_t& ofs) { // // .................memory.......................... // v1 p v2 // [--------------------] [-------] // // e.g., _find(p) == v1 // const pair<void*,DurableMappedFile*> x = *(--_views.upper_bound(p)); DurableMappedFile *mmf = x.second; if( mmf ) { size_t o = ((char *)p) - ((char*)x.first); if( o < mmf->length() ) { ofs = o; return mmf; } } return 0; } /** find associated MMF object for a given pointer. threadsafe @param ofs out returns offset into the view of the pointer, if found. @return the DurableMappedFile to which this pointer belongs. null if not found. */ DurableMappedFile* PointerToDurableMappedFile::find(void *p, /*out*/ size_t& ofs) { mutex::scoped_lock lk(_m); return find_inlock(p, ofs); } PointerToDurableMappedFile privateViews; // here so that it is precomputed... void DurableMappedFile::setPath(const std::string& f) { string suffix; string prefix; bool ok = str::rSplitOn(f, '.', prefix, suffix); uassert(13520, str::stream() << "DurableMappedFile only supports filenames in a certain format " << f, ok); if( suffix == "ns" ) _fileSuffixNo = dur::JEntry::DotNsSuffix; else _fileSuffixNo = (int) str::toUnsigned(suffix); _p = RelativePath::fromFullPath(storageGlobalParams.dbpath, prefix); } bool DurableMappedFile::open(const std::string& fname, bool sequentialHint) { LOG(3) << "mmf open " << fname << endl; setPath(fname); _view_write = mapWithOptions(fname.c_str(), sequentialHint ? SEQUENTIAL : 0); return finishOpening(); } bool DurableMappedFile::create(const std::string& fname, unsigned long long& len, bool sequentialHint) { LOG(3) << "mmf create " << fname << endl; setPath(fname); _view_write = map(fname.c_str(), len, sequentialHint ? SEQUENTIAL : 0); return finishOpening(); } bool DurableMappedFile::finishOpening() { LOG(3) << "mmf finishOpening " << (void*) _view_write << ' ' << filename() << " len:" << length() << endl; if( _view_write ) { if (storageGlobalParams.dur) { _view_private = createPrivateMap(); if( _view_private == 0 ) { msgasserted(13636, str::stream() << "file " << filename() << " open/create failed in createPrivateMap (look in log for more information)"); } privateViews.add(_view_private, this); // note that testIntent builds use this, even though it points to view_write then... } else { _view_private = _view_write; } return true; } return false; } DurableMappedFile::DurableMappedFile() : _willNeedRemap(false) { _view_write = _view_private = 0; } namespace dur { void closingFileNotification(); } DurableMappedFile::~DurableMappedFile() { try { LOG(3) << "mmf close " << filename() << endl; // Only notifiy the durability system if the file was actually opened if (view_write()) { dur::closingFileNotification(); } LockMongoFilesExclusive lk; privateViews.remove(_view_private); _view_write = _view_private = 0; MemoryMappedFile::close(); } catch(...) { error() << "exception in ~DurableMappedFile" << endl; } } }