diff options
author | Jason Carey <jcarey@argv.me> | 2019-03-05 10:32:38 -0500 |
---|---|---|
committer | Jason Carey <jcarey@argv.me> | 2019-03-06 11:57:59 -0500 |
commit | ef78ad0b398dbf4a891c18cd32881b12f91da794 (patch) | |
tree | c8725212e30983d1b609e63db175d0d69ef68ec4 | |
parent | 39b7722f44e2124ad46c19f95d4059985e7d4132 (diff) | |
download | mongo-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.cpp | 16 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/proxyscope.h | 3 |
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; }; |