| 203 | return new PooledTCPSocketStream(stream, this, remote); |
| 204 | } |
| 205 | uint64_t evict() { |
| 206 | // remove empty entry in fdmap |
| 207 | intrusive_list<StreamListNode> freelist; |
| 208 | uint64_t near_expire = TTL_us + now; |
| 209 | for (auto it = fdmap.begin(); it != fdmap.end();) { |
| 210 | auto& list = it->second; |
| 211 | uint64_t exp; |
| 212 | while (!list.empty() && now >= |
| 213 | (exp = list.front()->timeout.expiration())) { |
| 214 | freelist.push_back(list.pop_front()); |
| 215 | } |
| 216 | if (list.empty()) { |
| 217 | it = fdmap.erase(it); |
| 218 | } else { |
| 219 | near_expire = std::min(near_expire, exp); |
| 220 | it++; |
| 221 | } |
| 222 | } |
| 223 | for (auto node : freelist) { |
| 224 | rm_watch(node); |
| 225 | } |
| 226 | freelist.delete_all(); |
| 227 | assert(near_expire > now); |
| 228 | return sat_sub(near_expire, now); |
| 229 | } |
| 230 | |
| 231 | bool release(const EndPoint& ep, ISocketStream* stream) { |
| 232 | auto fd = stream->get_underlay_fd(); |