diff options
author | Tad Marshall <tad@10gen.com> | 2012-03-23 06:51:40 -0400 |
---|---|---|
committer | Tad Marshall <tad@10gen.com> | 2012-03-23 16:30:06 -0400 |
commit | c0ed1fde6a726909ae99b928a711e3c38837a4ae (patch) | |
tree | 3fc828378f66c9063e04783030fe5270b02c40aa /src/mongo/util/mmap_win.cpp | |
parent | 41db66ef99fbc0e499a366db8d341e787d17a7b1 (diff) | |
download | mongo-c0ed1fde6a726909ae99b928a711e3c38837a4ae.tar.gz |
SERVER-1163 Retry calls to FlushViewOfFile on error 33
FlushViewOfFile() will return error code 33 (ERROR_LOCK_VIOLATION)
in some cases, but this is a "transient" error, and just retrying
repeatedly will (supposedly) always work. This changes the code
to retry up to one million times and for up to 60 seconds if it
continues to get ERROR_LOCK_VIOLATION.
Diffstat (limited to 'src/mongo/util/mmap_win.cpp')
-rw-r--r-- | src/mongo/util/mmap_win.cpp | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/src/mongo/util/mmap_win.cpp b/src/mongo/util/mmap_win.cpp index feba75d66f4..93896404ca2 100644 --- a/src/mongo/util/mmap_win.cpp +++ b/src/mongo/util/mmap_win.cpp @@ -21,6 +21,7 @@ #include "../db/mongommf.h" #include "../db/concurrency.h" #include "../db/memconcept.h" +#include "mongo/util/timer.h" namespace mongo { @@ -169,13 +170,37 @@ namespace mongo { scoped_lock lk(*_flushMutex); - BOOL success = FlushViewOfFile(_view, 0); // 0 means whole mapping - if (!success) { - int err = GetLastError(); - out() << "FlushViewOfFile failed " << err << " file: " << _filename << endl; + int loopCount = 0; + bool success = false; + int dosError = ERROR_SUCCESS; + const int maximumLoopCount = 1000 * 1000; + const int maximumTimeInSeconds = 60; + Timer t; + while ( !success && loopCount < maximumLoopCount && t.seconds() < maximumTimeInSeconds ) { + ++loopCount; + success = FALSE != FlushViewOfFile( _view, 0 ); + if ( !success ) { + dosError = GetLastError(); + if ( dosError != ERROR_LOCK_VIOLATION ) { + break; + } + } + } + if ( success && loopCount > 1 ) { + log() << "FlushViewOfFile for " << _filename + << " succeeded after " << loopCount + << " attempts taking " << t.millis() + << " ms" << endl; + } + else if ( !success ) { + log() << "FlushViewOfFile for " << _filename + << " failed with error " << dosError + << " after " << loopCount + << " attempts taking " << t.millis() + << " ms" << endl; } - success = FlushFileBuffers(_fd); + success = FALSE != FlushFileBuffers(_fd); if (!success) { int err = GetLastError(); out() << "FlushFileBuffers failed " << err << " file: " << _filename << endl; |