summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTad Marshall <tad@10gen.com>2012-03-23 06:51:40 -0400
committerAndy Schwerin <schwerin@10gen.com>2012-04-18 16:25:29 -0400
commit83fa0f7bc1611e015024b6acac23b14cca44f35e (patch)
tree8c3ada65b6c93144ab96e1776cb6efe5688b7ed2
parent7460b30455b080fcb957248784871aa66538cb1c (diff)
downloadmongo-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.cpp37
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;