/** (SLOW) diagnostic to check that the private view and the non-private view are in sync. */ static void debugValidateMapsMatch() { if( !DebugValidateMapsMatch ) return; Timer t; set<MongoFile*>& files = MongoFile::getAllFiles(); for( set<MongoFile*>::iterator i = files.begin(); i != files.end(); i++ ) { MongoFile *mf = *i; if( mf->isMongoMMF() ) { MongoMMF *mmf = (MongoMMF*) mf; const char *p = (const char *) mmf->getView(); const char *w = (const char *) mmf->view_write(); unsigned low = 0xffffffff; unsigned high = 0; for( unsigned i = 0; i < mmf->length(); i++ ) { if( p[i] != w[i] ) { log() << i << '\t' << (int) p[i] << '\t' << (int) w[i] << endl; if( i < low ) low = i; if( i > high ) high = i; } } if( low != 0xffffffff ) { std::stringstream ss; ss << "dur error warning views mismatch " << mmf->filename() << ' ' << (hex) << low << ".." << high << " len:" << high-low+1; log() << ss.str() << endl; log() << "priv loc: " << (void*)(p+low) << endl; vector<WriteIntent>& w = commitJob.writes(); (void)w; // mark as unused. Useful for inspection in debugger breakpoint(); } } } log() << "debugValidateMapsMatch " << t.millis() << "ms " << endl; }
void MongoFile::unmarkAllWritable() { rwlock lk( mmmutex , false ); for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ MongoFile * mmf = *i; if (mmf) mmf->_unlock(); } }
void MongoFile::unmarkAllWritable() { if( cmdLine.dur ) return; RWLockRecursive::Shared lk(mmmutex); for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ) { MongoFile * mmf = *i; if (mmf) mmf->_unlock(); } }
void MongoFile::markAllWritable() { if( cmdLine.dur ) return; rwlock lk( mmmutex , false ); for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ) { MongoFile * mmf = *i; if (mmf) mmf->_lock(); } }
/*static*/ int MongoFile::flushAll( bool sync ){ int num = 0; rwlock lk( mmmutex , false ); for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ num++; MongoFile * mmf = *i; if ( ! mmf ) continue; mmf->flush( sync ); } return num; }
/*static*/ int MongoFile::_flushAll( bool sync ){ if ( ! sync ){ int num = 0; rwlock lk( mmmutex , false ); for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ num++; MongoFile * mmf = *i; if ( ! mmf ) continue; mmf->flush( sync ); } return num; } // want to do it sync set<MongoFile*> seen; while ( true ){ auto_ptr<Flushable> f; { rwlock lk( mmmutex , false ); for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ){ MongoFile * mmf = *i; if ( ! mmf ) continue; if ( seen.count( mmf ) ) continue; f.reset( mmf->prepareFlush() ); seen.insert( mmf ); break; } } if ( ! f.get() ) break; f->flush(); } return seen.size(); }
/*static*/ int MongoFile::_flushAll(bool sync) { if (!sync) { int num = 0; LockMongoFilesShared lk; for (set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++) { num++; MongoFile* mmf = *i; if (!mmf) continue; mmf->flush(sync); } return num; } // want to do it sync // get a thread-safe Flushable object for each file first in a single lock // so that we can iterate and flush without doing any locking here OwnedPointerVector<Flushable> thingsToFlushWrapper; vector<Flushable*>& thingsToFlush = thingsToFlushWrapper.mutableVector(); { LockMongoFilesShared lk; for (set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++) { MongoFile* mmf = *i; if (!mmf) continue; thingsToFlush.push_back(mmf->prepareFlush()); } } for (size_t i = 0; i < thingsToFlush.size(); i++) { thingsToFlush[i]->flush(); } return thingsToFlush.size(); }