void run() { if( cmdLine.syncdelay == 0 ) log() << "warning: --syncdelay 0 is not recommended and can have strange performance" << endl; else if( cmdLine.syncdelay == 1 ) log() << "--syncdelay 1" << endl; else if( cmdLine.syncdelay != 60 ) log(1) << "--syncdelay " << cmdLine.syncdelay << endl; int time_flushing = 0; while ( ! inShutdown() ) { flushDiagLog(); if ( cmdLine.syncdelay == 0 ) { // in case at some point we add an option to change at runtime sleepsecs(5); continue; } sleepmillis( (long long) std::max(0.0, (cmdLine.syncdelay * 1000) - time_flushing) ); if ( inShutdown() ) { // occasional issue trying to flush during shutdown when sleep interrupted break; } Date_t start = jsTime(); int numFiles = MemoryMappedFile::flushAll( true ); time_flushing = (int) (jsTime() - start); globalFlushCounters.flushed(time_flushing); log(1) << "flushing mmap took " << time_flushing << "ms " << " for " << numFiles << " files" << endl; } }
/** also called by ntservice.cpp */ void shutdownServer() { log() << "shutdown: going to close listening sockets..." << endl; ListeningSockets::get()->closeAll(); log() << "shutdown: going to flush diaglog..." << endl; flushDiagLog(); /* must do this before unmapping mem or you may get a seg fault */ log() << "shutdown: going to close sockets..." << endl; boost::thread close_socket_thread( boost::bind(MessagingPort::closeAllSockets, 0) ); // wait until file preallocation finishes // we would only hang here if the file_allocator code generates a // synchronous signal, which we don't expect log() << "shutdown: waiting for fs preallocator..." << endl; FileAllocator::get()->waitUntilFinished(); if( cmdLine.dur ) { log() << "shutdown: lock for final commit..." << endl; { int n = 10; while( 1 ) { // we may already be in a read lock from earlier in the call stack, so do read lock here // to be consistent with that. readlocktry w("", 20000); if( w.got() ) { log() << "shutdown: final commit..." << endl; getDur().commitNow(); break; } if( --n <= 0 ) { log() << "shutdown: couldn't acquire write lock, aborting" << endl; mongoAbort("couldn't acquire write lock"); } log() << "shutdown: waiting for write lock..." << endl; } } MemoryMappedFile::flushAll(true); } log() << "shutdown: closing all files..." << endl; stringstream ss3; MemoryMappedFile::closeAllFiles( ss3 ); log() << ss3.str() << endl; if( cmdLine.dur ) { dur::journalCleanup(true); } #if !defined(__sunos__) if ( lockFile ) { log() << "shutdown: removing fs lock..." << endl; /* This ought to be an unlink(), but Eliot says the last time that was attempted, there was a race condition with acquirePathLock(). */ #ifdef _WIN32 if( _chsize( lockFile , 0 ) ) log() << "couldn't remove fs lock " << WSAGetLastError() << endl; CloseHandle(lockFileHandle); #else if( ftruncate( lockFile , 0 ) ) log() << "couldn't remove fs lock " << errnoWithDescription() << endl; flock( lockFile, LOCK_UN ); #endif } #endif }