diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-03-16 11:48:45 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-03-18 12:40:44 -0400 |
commit | 0f6f2e9a199bff05c69ca5aace94a5ac8fe2cff3 (patch) | |
tree | d19d580d3af29919ec205e361015f421aa177686 /src/mongo/db | |
parent | 78541981780b9d3608ce6d43167e230ed03c6444 (diff) | |
download | mongo-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.cpp | 20 | ||||
-rw-r--r-- | src/mongo/db/exec/SConscript | 3 | ||||
-rw-r--r-- | src/mongo/db/instance.cpp | 23 | ||||
-rw-r--r-- | src/mongo/db/query/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/SConscript | 1 |
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, ) |