void NetworkInterfaceImpl::_consumeNetworkRequests() { stdx::unique_lock<stdx::mutex> lk(_mutex); while (!_inShutdown) { if (_pending.empty()) { if (_threads.size() > kMinThreads) { const Date_t nowDate = now(); const Date_t nextThreadRetirementDate = _lastFullUtilizationDate + kMaxIdleThreadAge; if (nowDate > nextThreadRetirementDate) { _lastFullUtilizationDate = nowDate; break; } } _hasPending.wait_for(lk, kMaxIdleThreadAge); continue; } CommandData todo = _pending.front(); _pending.pop_front(); ++_numActiveNetworkRequests; --_numIdleThreads; lk.unlock(); TaskExecutor::ResponseStatus result = _commandRunner.runCommand(todo.request); LOG(2) << "Network status of sending " << todo.request.cmdObj.firstElementFieldName() << " to " << todo.request.target << " was " << result.getStatus(); todo.onFinish(result); lk.lock(); --_numActiveNetworkRequests; ++_numIdleThreads; _signalWorkAvailable_inlock(); } --_numIdleThreads; if (_inShutdown) { return; } // This thread is ending because it was idle for too long. // Find self in _threads, remove self from _threads, detach self. for (size_t i = 0; i < _threads.size(); ++i) { if (_threads[i]->get_id() != stdx::this_thread::get_id()) { continue; } _threads[i]->detach(); _threads[i].swap(_threads.back()); _threads.pop_back(); return; } severe().stream() << "Could not find this thread, with id " << stdx::this_thread::get_id() << " in the replication networking thread pool"; fassertFailedNoTrace(28676); }
void NetworkInterfaceImpl::_runOneCommand() { stdx::unique_lock<stdx::mutex> lk(_mutex); if (_pending.empty()) { // This may happen if any commands were canceled. return; } CommandData todo = _pending.front(); _pending.pop_front(); ++_numActiveNetworkRequests; lk.unlock(); TaskExecutor::ResponseStatus result = _commandRunner.runCommand(todo.request); LOG(2) << "Network status of sending " << todo.request.cmdObj.firstElementFieldName() << " to " << todo.request.target << " was " << result.getStatus(); todo.onFinish(result); lk.lock(); --_numActiveNetworkRequests; _signalWorkAvailable_inlock(); }