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;
    }
Example #2
0
    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;
    }
Example #3
0
    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
        }
    }
Example #4
0
    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();
    }
Example #6
0
 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 );
     }
 }
Example #7
0
    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;
    }
Example #8
0
    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;
    }
Example #9
0
    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
        }
    }
Example #10
0
 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;
         }
     }
 }