summaryrefslogtreecommitdiff
path: root/src/mongo/shell/shell_utils_launcher.cpp
diff options
context:
space:
mode:
authorJason Carey <jcarey@argv.me>2015-11-05 11:09:55 -0500
committerJason Carey <jcarey@argv.me>2015-11-05 13:48:05 -0500
commitc6d730bfed0c3ec374b35c4fd5b2badaa9bd8fc6 (patch)
tree1703c6b088612770c47a5127dff94f396bb9e7ed /src/mongo/shell/shell_utils_launcher.cpp
parent0650d80cc4a77b489dd5f52e84d81d7c8c123468 (diff)
downloadmongo-c6d730bfed0c3ec374b35c4fd5b2badaa9bd8fc6.tar.gz
SERVER-21304 make ProgramRegistry::_handles thread safe
There is one global program registry in the shell for managing processes. That registry has a mutex, and uses it to protect it's internal lookup tables against concurrent access. On windows, it additionally has a map from pid to HANDLE, but offers this as a public member and makes no effort to ensure thread safe access. We need to bury access to that type behind methods and use the registry mutex to guard _handle inside.
Diffstat (limited to 'src/mongo/shell/shell_utils_launcher.cpp')
-rw-r--r--src/mongo/shell/shell_utils_launcher.cpp40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/mongo/shell/shell_utils_launcher.cpp b/src/mongo/shell/shell_utils_launcher.cpp
index 4729f12438d..a574e9ac2c9 100644
--- a/src/mongo/shell/shell_utils_launcher.cpp
+++ b/src/mongo/shell/shell_utils_launcher.cpp
@@ -163,6 +163,33 @@ void ProgramRegistry::getRegisteredPids(vector<ProcessId>& pids) {
}
}
+#ifdef _WIN32
+HANDLE ProgramRegistry::getHandleForPid(ProcessId pid) {
+ stdx::lock_guard<stdx::recursive_mutex> lk(_mutex);
+
+ return _handles[pid];
+}
+
+void ProgramRegistry::eraseHandleForPid(ProcessId pid) {
+ stdx::lock_guard<stdx::recursive_mutex> lk(_mutex);
+
+ _handles.erase(pid);
+}
+
+std::size_t ProgramRegistry::countHandleForPid(ProcessId pid) {
+ stdx::lock_guard<stdx::recursive_mutex> lk(_mutex);
+
+ return _handles.count(pid);
+}
+
+void ProgramRegistry::insertHandleForPid(ProcessId pid, HANDLE handle) {
+ stdx::lock_guard<stdx::recursive_mutex> lk(_mutex);
+
+ _handles.insert(make_pair(pid, handle));
+}
+
+#endif
+
ProgramRegistry& registry = *(new ProgramRegistry());
void goingAwaySoon() {
@@ -451,7 +478,7 @@ void ProgramRunner::launchProcess(int child_stdout) {
CloseHandle(pi.hThread);
_pid = ProcessId::fromNative(pi.dwProcessId);
- registry._handles.insert(make_pair(_pid, pi.hProcess));
+ registry.insertHandleForPid(_pid, pi.hProcess);
#else
@@ -502,8 +529,8 @@ void ProgramRunner::launchProcess(int child_stdout) {
// returns true if process exited
bool wait_for_pid(ProcessId pid, bool block = true, int* exit_code = NULL) {
#ifdef _WIN32
- verify(registry._handles.count(pid));
- HANDLE h = registry._handles[pid];
+ verify(registry.countHandleForPid(pid));
+ HANDLE h = registry.getHandleForPid(pid);
if (block) {
if (WaitForSingleObject(h, INFINITE)) {
@@ -519,7 +546,7 @@ bool wait_for_pid(ProcessId pid, bool block = true, int* exit_code = NULL) {
return false;
}
CloseHandle(h);
- registry._handles.erase(pid);
+ registry.eraseHandleForPid(pid);
if (exit_code)
*exit_code = tmp;
return true;
@@ -654,8 +681,9 @@ BSONObj CopyDbpath(const BSONObj& a, void* data) {
inline void kill_wrapper(ProcessId pid, int sig, int port, const BSONObj& opt) {
#ifdef _WIN32
if (sig == SIGKILL || port == 0) {
- verify(registry._handles.count(pid));
- TerminateProcess(registry._handles[pid], 1); // returns failure for "zombie" processes.
+ verify(registry.countHandleForPid(pid));
+ TerminateProcess(registry.getHandleForPid(pid),
+ 1); // returns failure for "zombie" processes.
return;
}