bool GlobalEnvironmentMongoD::killOperation(AtomicUInt opId) { scoped_lock clientLock(Client::clientsMutex); bool found = false; // XXX clean up { for( set< Client* >::const_iterator j = Client::clients.begin(); !found && j != Client::clients.end(); ++j ) { for( CurOp *k = ( *j )->curop(); !found && k; k = k->parent() ) { if ( k->opNum() != opId ) continue; k->kill(); for( CurOp *l = ( *j )->curop(); l; l = l->parent() ) { l->kill(); } found = true; } } } if ( found ) { interruptJs( &opId ); } return found; }
bool KillCurrentOp::_killImpl_inclientlock(AtomicUInt i, bool* pNotifyFlag /* = NULL */) { bool found = false; { for( set< Client* >::const_iterator j = Client::clients.begin(); !found && j != Client::clients.end(); ++j ) { for( CurOp *k = ( *j )->curop(); !found && k; k = k->parent() ) { if ( k->opNum() != i ) continue; k->kill(pNotifyFlag); for( CurOp *l = ( *j )->curop(); l; l = l->parent() ) { l->kill(); } found = true; } } } if ( found ) { interruptJs( &i ); } return found; }
void ClientCursor::staticYield( int micros , const StringData& ns , Record * rec ) { killCurrentOp.checkForInterrupt( false ); { auto_ptr<LockMongoFilesShared> lk; if ( rec ) { // need to lock this else rec->touch won't be safe file could disappear lk.reset( new LockMongoFilesShared() ); } dbtempreleasecond unlock; if ( unlock.unlocked() ) { if ( micros == -1 ) micros = Client::recommendedYieldMicros(); if ( micros > 0 ) sleepmicros( micros ); } else { CurOp * c = cc().curop(); while ( c->parent() ) c = c->parent(); warning() << "ClientCursor::yield can't unlock b/c of recursive lock" << " ns: " << ns << " top: " << c->info() << endl; } if ( rec ) rec->touch(); lk.reset(0); // need to release this before dbtempreleasecond } }
void ClientCursor::staticYield(int micros, const StringData& ns, const Record* rec) { bool haveReadLock = Lock::isReadLocked(); killCurrentOp.checkForInterrupt(); { auto_ptr<LockMongoFilesShared> lk; if ( rec ) { // need to lock this else rec->touch won't be safe file could disappear lk.reset( new LockMongoFilesShared() ); } dbtempreleasecond unlock; if ( unlock.unlocked() ) { if ( haveReadLock ) { // This sleep helps reader threads yield to writer threads. // Without this, the underlying reader/writer lock implementations // are not sufficiently writer-greedy. #ifdef _WIN32 SwitchToThread(); #else if ( micros == 0 ) { yieldOrSleepFor1Microsecond(); } else { sleepmicros(1); } #endif } else { if ( micros == -1 ) { sleepmicros(Client::recommendedYieldMicros()); } else if ( micros == 0 ) { yieldOrSleepFor1Microsecond(); } else if ( micros > 0 ) { sleepmicros( micros ); } } } else if ( Listener::getTimeTracker() == 0 ) { // we aren't running a server, so likely a repair, so don't complain } else { CurOp * c = cc().curop(); while ( c->parent() ) c = c->parent(); warning() << "ClientCursor::staticYield can't unlock b/c of recursive lock" << " ns: " << ns << " top: " << c->info() << endl; } if ( rec ) rec->touch(); lk.reset(0); // need to release this before dbtempreleasecond } }
Status OperationContextImpl::checkForInterruptNoAssert() { if (getGlobalServiceContext()->getKillAllOperations()) { return Status(ErrorCodes::InterruptedAtShutdown, "interrupted at shutdown"); } CurOp* curOp = CurOp::get(this); if (curOp->maxTimeHasExpired()) { markKilled(); return Status(ErrorCodes::ExceededTimeLimit, "operation exceeded time limit"); } MONGO_FAIL_POINT_BLOCK(checkForInterruptFail, scopedFailPoint) { if (opShouldFail(this, scopedFailPoint.getData())) { log() << "set pending kill on " << (curOp->parent() ? "nested" : "top-level") << " op " << getOpID() << ", for checkForInterruptFail"; markKilled(); } } if (isKillPending()) { return Status(ErrorCodes::Interrupted, "operation was interrupted"); } return Status::OK(); }
void KillCurrentOp::kill(AtomicUInt i) { bool found = false; { scoped_lock l( Client::clientsMutex ); for( set< Client* >::const_iterator j = Client::clients.begin(); !found && j != Client::clients.end(); ++j ) { for( CurOp *k = ( *j )->curop(); !found && k; k = k->parent() ) { if ( k->opNum() == i ) { k->kill(); for( CurOp *l = ( *j )->curop(); l != k; l = l->parent() ) { l->kill(); } found = true; } } } } if ( found ) { interruptJs( &i ); } }
bool GlobalEnvironmentMongoD::_killOperationsAssociatedWithClientAndOpId_inlock( Client* client, unsigned int opId) { for( CurOp *k = client->curop(); k; k = k->parent() ) { if ( k->opNum() != opId ) continue; k->kill(); for( CurOp *l = client->curop(); l; l = l->parent() ) { l->kill(); } for (size_t i = 0; i < _killOpListeners.size(); i++) { try { _killOpListeners[i]->interrupt(opId); } catch (...) { std::terminate(); } } return true; } return false; }
bool GlobalEnvironmentMongoD::killOperation(unsigned int opId) { boost::mutex::scoped_lock clientLock(Client::clientsMutex); bool found = false; // XXX clean up { for(ClientSet::const_iterator j = Client::clients.begin(); !found && j != Client::clients.end(); ++j ) { for( CurOp *k = ( *j )->curop(); !found && k; k = k->parent() ) { if ( k->opNum() != opId ) continue; k->kill(); for( CurOp *l = ( *j )->curop(); l; l = l->parent() ) { l->kill(); } found = true; } } } if (found) { for (size_t i = 0; i < _killOpListeners.size(); i++) { try { _killOpListeners[i]->interrupt(opId); } catch (...) { std::terminate(); } } } return found; }
void ClientCursor::staticYield( int micros , const StringData& ns , Record * rec ) { bool haveReadLock = Lock::isReadLocked(); killCurrentOp.checkForInterrupt( false ); { auto_ptr<LockMongoFilesShared> lk; if ( rec ) { // need to lock this else rec->touch won't be safe file could disappear lk.reset( new LockMongoFilesShared() ); } dbtempreleasecond unlock; if ( unlock.unlocked() ) { if ( haveReadLock ) { // don't sleep with a read lock } else { if ( micros == -1 ) micros = Client::recommendedYieldMicros(); if ( micros > 0 ) sleepmicros( micros ); } } else if ( Listener::getTimeTracker() == 0 ) { // we aren't running a server, so likely a repair, so don't complain } else { CurOp * c = cc().curop(); while ( c->parent() ) c = c->parent(); warning() << "ClientCursor::yield can't unlock b/c of recursive lock" << " ns: " << ns << " top: " << c->info() << endl; } if ( rec ) rec->touch(); lk.reset(0); // need to release this before dbtempreleasecond } }
void ClientCursor::staticYield( int micros , const StringData& ns ) { killCurrentOp.checkForInterrupt( false ); { dbtempreleasecond unlock; if ( unlock.unlocked() ) { if ( micros == -1 ) micros = Client::recommendedYieldMicros(); if ( micros > 0 ) sleepmicros( micros ); } else { CurOp * c = cc().curop(); while ( c->parent() ) c = c->parent(); warning() << "ClientCursor::yield can't unlock b/c of recursive lock" << " ns: " << ns << " top: " << c->info() << endl; } } }