in wangle/acceptor/ConnectionManager.cpp [182:232]
void ConnectionManager::DrainHelper::drainConnections() {
DestructorGuard g(&manager_);
size_t numCleared = 0;
size_t numKept = 0;
auto it = manager_.drainIterator_;
CHECK(
shutdownState_ == ShutdownState::NOTIFY_PENDING_SHUTDOWN ||
shutdownState_ == ShutdownState::CLOSE_WHEN_IDLE);
while (it != manager_.conns_.end() && (numKept + numCleared) < 64) {
ManagedConnection& conn = *it++;
if (shutdownState_ == ShutdownState::NOTIFY_PENDING_SHUTDOWN) {
conn.fireNotifyPendingShutdown();
numKept++;
} else { // CLOSE_WHEN_IDLE
// Second time around: close idle sessions. If they aren't idle yet,
// have them close when they are idle
if (conn.isBusy()) {
numKept++;
} else {
numCleared++;
}
conn.fireCloseWhenIdle(!manager_.notifyPendingShutdown_);
}
}
if (shutdownState_ == ShutdownState::CLOSE_WHEN_IDLE) {
VLOG(2) << "Idle connections cleared: " << numCleared
<< ", busy conns kept: " << numKept;
} else {
VLOG(3) << this << " notified n=" << numKept;
}
manager_.drainIterator_ = it;
if (it != manager_.conns_.end()) {
manager_.eventBase_->runInLoop(this);
} else {
if (shutdownState_ == ShutdownState::NOTIFY_PENDING_SHUTDOWN) {
VLOG(3) << this << " finished notify_pending_shutdown";
shutdownState_ = ShutdownState::NOTIFY_PENDING_SHUTDOWN_COMPLETE;
if (!isScheduled()) {
// The idle grace timer already fired, start over immediately
shutdownState_ = ShutdownState::CLOSE_WHEN_IDLE;
manager_.drainIterator_ = drainStartIterator();
manager_.eventBase_->runInLoop(this);
}
} else {
shutdownState_ = ShutdownState::CLOSE_WHEN_IDLE_COMPLETE;
}
}
}