| 2162 | |
| 2163 | |
| 2164 | void SocketManager::close(int_fd s) |
| 2165 | { |
| 2166 | Option<UPID> proxy; // Some if an `HttpProxy` needs to be terminated. |
| 2167 | |
| 2168 | synchronized (mutex) { |
| 2169 | // This socket might not be active if it was already asked to get |
| 2170 | // closed (e.g., a write on the socket failed so we try and close |
| 2171 | // it and then later the recv side of the socket gets closed so we |
| 2172 | // try and close it again). Thus, ignore the request if we don't |
| 2173 | // know about the socket. |
| 2174 | if (sockets.count(s) > 0) { |
| 2175 | // Clean up any remaining encoders for this socket. |
| 2176 | if (outgoing.count(s) > 0) { |
| 2177 | while (!outgoing[s].empty()) { |
| 2178 | Encoder* encoder = outgoing[s].front(); |
| 2179 | delete encoder; |
| 2180 | outgoing[s].pop(); |
| 2181 | } |
| 2182 | |
| 2183 | outgoing.erase(s); |
| 2184 | } |
| 2185 | |
| 2186 | // Clean up after sockets used for remote communication. |
| 2187 | Option<Address> address = addresses.get(s); |
| 2188 | if (address.isSome()) { |
| 2189 | // Don't bother invoking `exited` unless socket was persistent. |
| 2190 | if (persists.count(address.get()) > 0 && persists[address.get()] == s) { |
| 2191 | persists.erase(address.get()); |
| 2192 | exited(address.get()); // Generate ExitedEvent(s)! |
| 2193 | } else if (temps.count(address.get()) > 0 && |
| 2194 | temps[address.get()] == s) { |
| 2195 | temps.erase(address.get()); |
| 2196 | } |
| 2197 | |
| 2198 | addresses.erase(s); |
| 2199 | } |
| 2200 | |
| 2201 | // Clean up any proxy associated with this socket. |
| 2202 | if (proxies.count(s) > 0) { |
| 2203 | proxy = proxies.at(s)->self(); |
| 2204 | proxies.erase(s); |
| 2205 | } |
| 2206 | |
| 2207 | dispose.erase(s); |
| 2208 | auto iterator = sockets.find(s); |
| 2209 | |
| 2210 | // We need to stop any 'ignore_data' receivers as they may have |
| 2211 | // the last Socket reference so we shutdown recvs but don't do a |
| 2212 | // full close (since that will be taken care of by ~Socket, see |
| 2213 | // comment below). Calling 'shutdown' will trigger 'ignore_data' |
| 2214 | // which will get back a 0 (i.e., EOF) when it tries to 'recv' |
| 2215 | // from the socket. Note we need to do this before we call |
| 2216 | // 'sockets.erase(s)' to avoid the potential race with the last |
| 2217 | // reference being in 'sockets'. |
| 2218 | |
| 2219 | // Hold on to the Socket and remove it from the 'sockets' map so |
| 2220 | // that in the case where 'shutdown()' ends up calling close the |
| 2221 | // termination logic is not run twice. |
no test coverage detected