void SearchWidget::performIncrementalSearch() { searcher()->stopTrackingViewport(); searcher()->restoreViewport(); if (searcher()->find(lineEdit_->text(), searchFlags())) { indicateSuccess(); } else { searcher()->restoreViewport(); indicateFailure(); } searcher()->startTrackingViewport(); }
void SearchWidget::findPrevious() { searcher()->stopTrackingViewport(); searcher()->restoreViewport(); if (searcher()->find(lineEdit_->text(), searchFlags() | Searcher::FindBackward)) { searcher()->rememberViewport(); indicateSuccess(); } else { searcher()->restoreViewport(); indicateFailure(); } searcher()->startTrackingViewport(); }
// NOTE: This method may only be called by ASIO threads // (do not call from methods entered by TaskExecutor threads) void NetworkInterfaceASIO::_completeOperation(AsyncOp* op, ResponseStatus resp) { auto metadata = op->getResponseMetadata(); if (!metadata.isEmpty()) { resp.metadata = metadata; } // Cancel this operation's timeout. Note that the timeout callback may already be running, // may have run, or may have already been scheduled to run in the near future. if (op->_timeoutAlarm) { op->_timeoutAlarm->cancel(); } if (resp.status.code() == ErrorCodes::ExceededTimeLimit) { _numTimedOutOps.fetchAndAdd(1); } if (op->_inSetup) { // If we are in setup we should only be here if we failed to connect. MONGO_ASIO_INVARIANT(!resp.isOK(), "Failed to connect in setup", op); // If we fail during connection, we won't be able to access any of op's members after // calling finish(), so we return here. log() << "Failed to connect to " << op->request().target << " - " << resp.status; _numFailedOps.fetchAndAdd(1); op->finish(resp); return; } if (op->_inRefresh) { // If we are in refresh we should only be here if we failed to heartbeat. MONGO_ASIO_INVARIANT(!resp.isOK(), "In refresh, but did not fail to heartbeat", op); // If we fail during heartbeating, we won't be able to access any of op's members after // calling finish(), so we return here. log() << "Failed asio heartbeat to " << op->request().target << " - " << redact(resp.status); _numFailedOps.fetchAndAdd(1); op->finish(resp); return; } if (!resp.isOK()) { // In the case that resp is not OK, but _inSetup is false, we are using a connection // that // we got from the pool to execute a command, but it failed for some reason. LOG(2) << "Failed to execute command: " << redact(op->request().toString()) << " reason: " << redact(resp.status); if (resp.status.code() != ErrorCodes::CallbackCanceled) { _numFailedOps.fetchAndAdd(1); } } else { _numSucceededOps.fetchAndAdd(1); } std::unique_ptr<AsyncOp> ownedOp; { stdx::lock_guard<stdx::mutex> lk(_inProgressMutex); auto iter = _inProgress.find(op); MONGO_ASIO_INVARIANT_INLOCK( iter != _inProgress.end(), "Could not find AsyncOp in _inProgress", op); ownedOp = std::move(iter->second); _inProgress.erase(iter); } op->finish(resp); MONGO_ASIO_INVARIANT(static_cast<bool>(ownedOp), "Invalid AsyncOp", op); auto conn = std::move(op->_connectionPoolHandle); auto asioConn = static_cast<connection_pool_asio::ASIOConnection*>(conn.get()); // Prevent any other threads or callbacks from accessing this op so we may safely complete // and destroy it. It is key that we do this after we remove the op from the _inProgress map // or someone else in cancelCommand could read the bumped generation and cancel the next // command that uses this op. See SERVER-20556. { stdx::lock_guard<stdx::mutex> lk(op->_access->mutex); ++(op->_access->id); } // We need to bump the generation BEFORE we call reset() or we could flip the timeout in the // timeout callback before returning the AsyncOp to the pool. ownedOp->reset(); asioConn->bindAsyncOp(std::move(ownedOp)); if (!resp.isOK()) { asioConn->indicateFailure(resp.status); } else { asioConn->indicateUsed(); asioConn->indicateSuccess(); } signalWorkAvailable(); }