| 384 | } |
| 385 | |
| 386 | void SocketMap::WatchConnections() { |
| 387 | std::vector<SocketId> main_sockets; |
| 388 | std::vector<SocketId> pooled_sockets; |
| 389 | std::vector<SocketMapKey> orphan_sockets; |
| 390 | const uint64_t CHECK_INTERVAL_US = 1000000UL; |
| 391 | while (bthread_usleep(CHECK_INTERVAL_US) == 0) { |
| 392 | // NOTE: save the gflag which may be reloaded at any time. |
| 393 | const int idle_seconds = _options.idle_timeout_second_dynamic ? |
| 394 | *_options.idle_timeout_second_dynamic |
| 395 | : _options.idle_timeout_second; |
| 396 | if (idle_seconds > 0) { |
| 397 | // Check idle pooled connections |
| 398 | List(&main_sockets); |
| 399 | for (auto main_socket : main_sockets) { |
| 400 | SocketUniquePtr s; |
| 401 | if (Socket::Address(main_socket, &s) == 0) { |
| 402 | s->ListPooledSockets(&pooled_sockets); |
| 403 | for (size_t i = FLAGS_reserve_one_idle_socket ? 1 : 0; |
| 404 | i < pooled_sockets.size(); ++i) { |
| 405 | SocketUniquePtr s2; |
| 406 | if (Socket::Address(pooled_sockets[i], &s2) == 0) { |
| 407 | s2->ReleaseReferenceIfIdle(idle_seconds); |
| 408 | } |
| 409 | } |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | // Check connections without Channel. This works when `defer_seconds' |
| 415 | // <= 0, in which case orphan connections will be closed immediately |
| 416 | // NOTE: save the gflag which may be reloaded at any time |
| 417 | const int defer_seconds = _options.defer_close_second_dynamic ? |
| 418 | *_options.defer_close_second_dynamic : |
| 419 | _options.defer_close_second; |
| 420 | ListOrphans(defer_seconds * 1000000L, &orphan_sockets); |
| 421 | for (size_t i = 0; i < orphan_sockets.size(); ++i) { |
| 422 | RemoveInternal(orphan_sockets[i], INVALID_SOCKET_ID, true); |
| 423 | } |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | } // namespace brpc |
no test coverage detected