| 244 | } |
| 245 | |
| 246 | void ReactorThread::ShutdownInternal() { |
| 247 | DCHECK(IsCurrentThread()); |
| 248 | |
| 249 | // Tear down any outbound TCP connections. |
| 250 | Status service_unavailable = ShutdownError(false); |
| 251 | VLOG(1) << name() << ": tearing down outbound TCP connections..."; |
| 252 | for (const auto& elem : client_conns_) { |
| 253 | const auto& conn = elem.second; |
| 254 | VLOG(1) << name() << ": shutting down " << conn->ToString(); |
| 255 | conn->Shutdown(service_unavailable); |
| 256 | } |
| 257 | client_conns_.clear(); |
| 258 | |
| 259 | // Tear down any inbound TCP connections. |
| 260 | VLOG(1) << name() << ": tearing down inbound TCP connections..."; |
| 261 | for (const auto& conn : server_conns_) { |
| 262 | VLOG(1) << name() << ": shutting down " << conn->ToString(); |
| 263 | conn->Shutdown(service_unavailable); |
| 264 | } |
| 265 | server_conns_.clear(); |
| 266 | |
| 267 | // Abort any scheduled tasks. |
| 268 | // |
| 269 | // These won't be found in the ReactorThread's list of pending tasks |
| 270 | // because they've been "run" (that is, they've been scheduled). |
| 271 | Status aborted = ShutdownError(true); // aborted |
| 272 | while (!scheduled_tasks_.empty()) { |
| 273 | DelayedTask* t = &scheduled_tasks_.front(); |
| 274 | scheduled_tasks_.pop_front(); |
| 275 | t->Abort(aborted); // should also free the task. |
| 276 | } |
| 277 | |
| 278 | // Remove the OpenSSL thread state. |
| 279 | // |
| 280 | // As of OpenSSL 1.1, this [1] is a no-op and can be ignored. |
| 281 | // |
| 282 | // 1. https://www.openssl.org/docs/man1.1.0/crypto/ERR_remove_thread_state.html |
| 283 | #if OPENSSL_VERSION_NUMBER < 0x10100000L |
| 284 | ERR_remove_thread_state(nullptr); |
| 285 | #endif |
| 286 | } |
| 287 | |
| 288 | ReactorTask::ReactorTask() { |
| 289 | } |