diff options
author | Tad Marshall <tad@10gen.com> | 2012-03-23 06:51:40 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@10gen.com> | 2012-04-18 16:25:29 -0400 |
commit | 83fa0f7bc1611e015024b6acac23b14cca44f35e (patch) | |
tree | 8c3ada65b6c93144ab96e1776cb6efe5688b7ed2 | |
parent | 7460b30455b080fcb957248784871aa66538cb1c (diff) | |
download | mongo-83fa0f7bc1611e015024b6acac23b14cca44f35e.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.
-rw-r--r-- | util/mmap_win.cpp | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/util/mmap_win.cpp b/util/mmap_win.cpp index 9173d7b35da..71bcceb0617 100644 --- a/util/mmap_win.cpp +++ b/util/mmap_win.cpp @@ -20,6 +20,7 @@ #include "text.h" #include "../db/mongommf.h" #include "../db/concurrency.h" +#include "timer.h" namespace mongo { @@ -166,13 +167,39 @@ 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; + bool timeout = false; + int dosError = ERROR_SUCCESS; + const int maximumLoopCount = 1000 * 1000; + const int maximumTimeInSeconds = 60; + Timer t; + while ( !success && !timeout && loopCount < maximumLoopCount ) { + ++loopCount; + success = FALSE != FlushViewOfFile( _view, 0 ); + if ( !success ) { + dosError = GetLastError(); + if ( dosError != ERROR_LOCK_VIOLATION ) { + break; + } + timeout = t.seconds() > maximumTimeInSeconds; + } + } + 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; |