diff options
-rw-r--r-- | src/mongo/db/curop.cpp | 14 | ||||
-rw-r--r-- | src/mongo/db/curop.h | 6 | ||||
-rw-r--r-- | src/mongo/db/kill_current_op.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/kill_current_op.h | 9 |
4 files changed, 7 insertions, 38 deletions
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp index a518b63b54b..9aee933f278 100644 --- a/src/mongo/db/curop.cpp +++ b/src/mongo/db/curop.cpp @@ -81,7 +81,6 @@ namespace mongo { _message = ""; _progressMeter.finished(); _killPending.store(0); - killCurrentOp.notifyAllWaiters(); _numYields = 0; _expectedLatencyMs = 0; _lockStat.reset(); @@ -126,8 +125,6 @@ namespace mongo { } CurOp::~CurOp() { - killCurrentOp.notifyAllWaiters(); - if ( _wrapped ) { scoped_lock bl(Client::clientsMutex); _client->_curOp = _wrapped; @@ -250,17 +247,8 @@ namespace mongo { return bob.obj(); } - void CurOp::setKillWaiterFlags() { - for (size_t i = 0; i < _notifyList.size(); ++i) - *(_notifyList[i]) = true; - _notifyList.clear(); - } - - void CurOp::kill(bool* pNotifyFlag /* = NULL */) { + void CurOp::kill() { _killPending.store(1); - if (pNotifyFlag) { - _notifyList.push_back(pNotifyFlag); - } } void CurOp::setMaxTimeMicros(uint64_t maxTimeMicros) { diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h index b8ce392f6e7..4c561192f37 100644 --- a/src/mongo/db/curop.h +++ b/src/mongo/db/curop.h @@ -298,7 +298,7 @@ namespace mongo { std::string getMessage() const { return _message.toString(); } ProgressMeter& getProgressMeter() { return _progressMeter; } CurOp *parent() const { return _wrapped; } - void kill(bool* pNotifyFlag = NULL); + void kill(); bool killPendingStrict() const { return _killPending.load(); } bool killPending() const { return _killPending.loadRelaxed(); } void yielded() { _numYields++; } @@ -313,8 +313,6 @@ namespace mongo { const LockStat& lockStat() const { return _lockStat; } LockStat& lockStat() { return _lockStat; } - void setKillWaiterFlags(); - /** * this should be used very sparingly * generally the Context should set this up @@ -347,8 +345,6 @@ namespace mongo { AtomicInt32 _killPending; int _numYields; LockStat _lockStat; - // _notifyList is protected by the global killCurrentOp's mtx. - std::vector<bool*> _notifyList; // this is how much "extra" time a query might take // a writebacklisten for example will block for 30s diff --git a/src/mongo/db/kill_current_op.cpp b/src/mongo/db/kill_current_op.cpp index 7ec7888045f..437a6ffa788 100644 --- a/src/mongo/db/kill_current_op.cpp +++ b/src/mongo/db/kill_current_op.cpp @@ -74,7 +74,7 @@ namespace mongo { return _killImpl_inclientlock(i); } - bool KillCurrentOp::_killImpl_inclientlock(AtomicUInt i, bool* pNotifyFlag /* = NULL */) { + bool KillCurrentOp::_killImpl_inclientlock(AtomicUInt i) { bool found = false; { for( set< Client* >::const_iterator j = Client::clients.begin(); @@ -85,7 +85,7 @@ namespace mongo { if ( k->opNum() != i ) continue; - k->kill(pNotifyFlag); + k->kill(); for( CurOp *l = ( *j )->curop(); l; l = l->parent() ) { l->kill(); } @@ -100,14 +100,6 @@ namespace mongo { return found; } - - void KillCurrentOp::notifyAllWaiters() { - boost::unique_lock<boost::mutex> lck(_mtx); - if (!haveClient()) - return; - cc().curop()->setKillWaiterFlags(); - } - namespace { // Global state for checkForInterrupt fail point. @@ -150,9 +142,9 @@ namespace { if (c.curop()->maxTimeHasExpired()) { c.curop()->kill(); - notifyAllWaiters(); uasserted(ErrorCodes::ExceededTimeLimit, "operation exceeded time limit"); } + MONGO_FAIL_POINT_BLOCK(checkForInterruptFail, scopedFailPoint) { if (opShouldFail(c, scopedFailPoint.getData())) { log() << "set pending kill on " << (c.curop()->parent() ? "nested" : "top-level") @@ -160,8 +152,8 @@ namespace { c.curop()->kill(); } } + if (c.curop()->killPending()) { - notifyAllWaiters(); uasserted(11601, "operation was interrupted"); } } diff --git a/src/mongo/db/kill_current_op.h b/src/mongo/db/kill_current_op.h index 5f1db6a6271..55557d0b194 100644 --- a/src/mongo/db/kill_current_op.h +++ b/src/mongo/db/kill_current_op.h @@ -65,25 +65,18 @@ namespace mongo { /** @return "" if not interrupted. otherwise, you should stop. */ const char *checkForInterruptNoAssert(); - /** set all flags for all the threads waiting for the current thread's operation to - * end; part of internal synchronous kill mechanism - **/ - void notifyAllWaiters(); - /** Reset the object to its initial state. Only for testing. */ void reset(); private: void interruptJs( AtomicUInt *op ); volatile bool _globalKill; - boost::mutex _mtx; /** * @param i opid of operation to kill - * @param pNotifyFlag optional bool to be set to true when kill actually happens * @return if operation was found **/ - bool _killImpl_inclientlock(AtomicUInt i, bool* pNotifyFlag = NULL); + bool _killImpl_inclientlock(AtomicUInt i); }; extern KillCurrentOp killCurrentOp; |