summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Carey <jcarey@argv.me>2019-03-05 10:32:38 -0500
committerJason Carey <jcarey@argv.me>2019-03-06 11:57:59 -0500
commitef78ad0b398dbf4a891c18cd32881b12f91da794 (patch)
treec8725212e30983d1b609e63db175d0d69ef68ec4
parent39b7722f44e2124ad46c19f95d4059985e7d4132 (diff)
downloadmongo-ef78ad0b398dbf4a891c18cd32881b12f91da794.tar.gz
SERVER-39961 Update proxy scope to use two cvs
Our proxyscope type currently uses one condition variable to wait/notify from the caller and the callee threads. It's been pointed out that this may not be safe on older versions of glibc, as there used to be a different understanding of whether or not it was acceptable for a condvar notify to notify the thread which called notify (if it later called wait). See http://austingroupbugs.net/view.php?id=609
-rw-r--r--src/mongo/scripting/mozjs/proxyscope.cpp16
-rw-r--r--src/mongo/scripting/mozjs/proxyscope.h3
2 files changed, 11 insertions, 8 deletions
diff --git a/src/mongo/scripting/mozjs/proxyscope.cpp b/src/mongo/scripting/mozjs/proxyscope.cpp
index afc21eca1eb..b6ccdf26d08 100644
--- a/src/mongo/scripting/mozjs/proxyscope.cpp
+++ b/src/mongo/scripting/mozjs/proxyscope.cpp
@@ -51,7 +51,6 @@ MozJSProxyScope::MozJSProxyScope(MozJSScriptEngine* engine)
_mutex(),
_state(State::Idle),
_status(Status::OK()),
- _condvar(),
// Despite calling PR_CreateThread, we're actually using our own
// implementation of PosixNSPR.cpp in this directory. So these threads
// are actually hosted on top of stdx::threads and most of the flags
@@ -292,19 +291,21 @@ void MozJSProxyScope::runOnImplThread(unique_function<void()> f) {
invariant(_state == State::Idle);
_state = State::ProxyRequest;
- _condvar.notify_one();
+ lk.unlock();
+ _implCondvar.notify_one();
+ lk.lock();
Interruptible* interruptible = _opCtx ? _opCtx : Interruptible::notInterruptible();
auto pred = [&] { return _state == State::ImplResponse; };
try {
- interruptible->waitForConditionOrInterrupt(_condvar, lk, pred);
+ interruptible->waitForConditionOrInterrupt(_proxyCondvar, lk, pred);
} catch (const DBException& ex) {
_status = ex.toStatus();
_implScope->kill();
- _condvar.wait(lk, pred);
+ _proxyCondvar.wait(lk, pred);
}
_state = State::Idle;
@@ -327,7 +328,7 @@ void MozJSProxyScope::shutdownThread() {
_state = State::Shutdown;
}
- _condvar.notify_one();
+ _implCondvar.notify_one();
PR_JoinThread(_thread);
}
@@ -370,7 +371,7 @@ void MozJSProxyScope::implThread(void* arg) {
stdx::unique_lock<stdx::mutex> lk(proxy->_mutex);
{
MONGO_IDLE_THREAD_BLOCK;
- proxy->_condvar.wait(lk, [proxy] {
+ proxy->_implCondvar.wait(lk, [proxy] {
return proxy->_state == State::ProxyRequest || proxy->_state == State::Shutdown;
});
}
@@ -388,7 +389,8 @@ void MozJSProxyScope::implThread(void* arg) {
proxy->_state = State::ImplResponse;
- proxy->_condvar.notify_one();
+ lk.unlock();
+ proxy->_proxyCondvar.notify_one();
}
}
diff --git a/src/mongo/scripting/mozjs/proxyscope.h b/src/mongo/scripting/mozjs/proxyscope.h
index 607c3d2b4b2..ddaa9c815ec 100644
--- a/src/mongo/scripting/mozjs/proxyscope.h
+++ b/src/mongo/scripting/mozjs/proxyscope.h
@@ -200,7 +200,8 @@ private:
Status _status;
OperationContext* _opCtx = nullptr;
- stdx::condition_variable _condvar;
+ stdx::condition_variable _proxyCondvar;
+ stdx::condition_variable _implCondvar;
PRThread* _thread;
};