summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2015-03-16 11:48:45 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2015-03-18 12:40:44 -0400
commit0f6f2e9a199bff05c69ca5aace94a5ac8fe2cff3 (patch)
treed19d580d3af29919ec205e361015f421aa177686 /src/mongo/db
parent78541981780b9d3608ce6d43167e230ed03c6444 (diff)
downloadmongo-0f6f2e9a199bff05c69ca5aace94a5ac8fe2cff3.tar.gz
SERVER-17570: Fix NT Service shutdown race condition
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/dbcommands_generic.cpp20
-rw-r--r--src/mongo/db/exec/SConscript3
-rw-r--r--src/mongo/db/instance.cpp23
-rw-r--r--src/mongo/db/query/SConscript2
-rw-r--r--src/mongo/db/repl/SConscript1
-rw-r--r--src/mongo/db/storage/mmap_v1/SConscript1
-rw-r--r--src/mongo/db/storage/wiredtiger/SConscript1
7 files changed, 44 insertions, 7 deletions
diff --git a/src/mongo/db/dbcommands_generic.cpp b/src/mongo/db/dbcommands_generic.cpp
index 0ccff8711ba..c4f705f6dd0 100644
--- a/src/mongo/db/dbcommands_generic.cpp
+++ b/src/mongo/db/dbcommands_generic.cpp
@@ -58,6 +58,7 @@
#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
#include "mongo/util/md5.hpp"
+#include "mongo/util/ntservice.h"
#include "mongo/util/processinfo.h"
#include "mongo/util/ramlog.h"
#include "mongo/util/version_reporting.h"
@@ -323,8 +324,23 @@ namespace mongo {
log() << "terminating, shutdown command received" << endl;
- exitCleanly(EXIT_CLEAN); // this never returns
- invariant(false);
+#if defined(_WIN32)
+ // Signal the ServiceMain thread to shutdown.
+ if(ntservice::shouldStartService()) {
+ signalShutdown();
+
+ // Client expects us to abruptly close the socket as part of exiting
+ // so this function is not allowed to return.
+ // The ServiceMain thread will quit for us so just sleep until it does.
+ while (true)
+ sleepsecs(60); // Loop forever
+ }
+ else
+#endif
+ {
+ exitCleanly(EXIT_CLEAN); // this never returns
+ invariant(false);
+ }
}
/* for testing purposes only */
diff --git a/src/mongo/db/exec/SConscript b/src/mongo/db/exec/SConscript
index 37e91bd8476..f8f35573827 100644
--- a/src/mongo/db/exec/SConscript
+++ b/src/mongo/db/exec/SConscript
@@ -87,6 +87,7 @@ env.CppUnitTest(
"$BUILD_DIR/mongo/coreserver",
"$BUILD_DIR/mongo/coredb",
"$BUILD_DIR/mongo/mocklib",
+ "$BUILD_DIR/mongo/ntservice_mock",
],
NO_CRUTCH = True,
)
@@ -102,6 +103,7 @@ env.CppUnitTest(
"$BUILD_DIR/mongo/coreserver",
"$BUILD_DIR/mongo/coredb",
"$BUILD_DIR/mongo/mocklib",
+ "$BUILD_DIR/mongo/ntservice_mock",
],
NO_CRUTCH = True,
)
@@ -116,6 +118,7 @@ env.CppUnitTest(
"$BUILD_DIR/mongo/serveronly",
"$BUILD_DIR/mongo/coreserver",
"$BUILD_DIR/mongo/coredb",
+ "$BUILD_DIR/mongo/ntservice_mock",
],
NO_CRUTCH = True,
)
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index 9e3ca6438f9..3f19f5769f1 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -1105,12 +1105,25 @@ namespace mongo {
getGlobalEnvironment()->shutdownGlobalStorageEngineCleanly();
}
+ // shutdownLock
+ //
+ // Protects:
+ // Ensures shutdown is single threaded.
+ // Lock Ordering:
+ // No restrictions
+ boost::mutex shutdownLock;
+
+ void signalShutdown() {
+ // Notify all threads shutdown has started
+ shutdownInProgress.fetchAndAdd(1);
+ }
+
void exitCleanly(ExitCode code) {
- if (shutdownInProgress.compareAndSwap(0, 1) != 0) {
- while (true) {
- sleepsecs(1000);
- }
- }
+ // Notify all threads shutdown has started
+ shutdownInProgress.fetchAndAdd(1);
+
+ // Grab the shutdown lock to prevent concurrent callers
+ boost::lock_guard<boost::mutex> lockguard(shutdownLock);
// Global storage engine may not be started in all cases before we exit
if (getGlobalEnvironment()->getGlobalStorageEngine() == NULL) {
diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript
index 6f2af6b5f2e..bc9b62945e2 100644
--- a/src/mongo/db/query/SConscript
+++ b/src/mongo/db/query/SConscript
@@ -61,6 +61,7 @@ env.CppUnitTest(
"$BUILD_DIR/mongo/coreserver",
"$BUILD_DIR/mongo/coredb",
"$BUILD_DIR/mongo/mocklib",
+ "$BUILD_DIR/mongo/ntservice_mock",
],
NO_CRUTCH = True,
)
@@ -236,6 +237,7 @@ env.CppUnitTest(
"$BUILD_DIR/mongo/coreserver",
"$BUILD_DIR/mongo/coredb",
"$BUILD_DIR/mongo/mocklib",
+ "$BUILD_DIR/mongo/ntservice_mock",
],
NO_CRUTCH = True,
)
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index f4709cb2d8c..dae6b5c3f0e 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -209,5 +209,6 @@ env.CppUnitTest('isself_test',
'$BUILD_DIR/mongo/serveronly',
'$BUILD_DIR/mongo/coreserver',
'$BUILD_DIR/mongo/coredb',
+ "$BUILD_DIR/mongo/ntservice_mock",
],
NO_CRUTCH = True)
diff --git a/src/mongo/db/storage/mmap_v1/SConscript b/src/mongo/db/storage/mmap_v1/SConscript
index 69c20e8b39e..bacd25fa446 100644
--- a/src/mongo/db/storage/mmap_v1/SConscript
+++ b/src/mongo/db/storage/mmap_v1/SConscript
@@ -89,6 +89,7 @@ env.CppUnitTest(
'$BUILD_DIR/mongo/serveronly',
'$BUILD_DIR/mongo/coreserver',
'$BUILD_DIR/mongo/coredb',
+ '$BUILD_DIR/mongo/ntservice_mock',
],
NO_CRUTCH=True,
)
diff --git a/src/mongo/db/storage/wiredtiger/SConscript b/src/mongo/db/storage/wiredtiger/SConscript
index dc0ccc3be30..5b58b579681 100644
--- a/src/mongo/db/storage/wiredtiger/SConscript
+++ b/src/mongo/db/storage/wiredtiger/SConscript
@@ -88,6 +88,7 @@ if wiredtiger:
'$BUILD_DIR/mongo/serveronly',
'$BUILD_DIR/mongo/coreserver',
'$BUILD_DIR/mongo/coredb',
+ '$BUILD_DIR/mongo/ntservice_mock',
],
NO_CRUTCH=True,
)