ConnectBG handles asynchronous connects by spinning up a background thread to call ::connect(). We kick that thread out of connect, after a timeout, by calling close. This isn't safe because:
Thread A: Your call to Socket::connect() Thread B: BG connector for A Thread C: Unrelated thread calling Socket::connect() Thread D: BG connector for C Thread A Thread B Thread C Thread D Start Thread B connect(N) Wait 4.9999 seconds get EINTR Trigger timeout shutdown(N) close(N) N = socket() connect(N) connect(N) errno == EISCONN
Which can lead us to connect a fd to the wrong endpoint.
We can work around this by only calling shutdown from the parent thread, waiting for the child to join, then calling close.
- is duplicated by
-
SERVER-13375 don't rely on ConnectBG thread for nonblocking connect
- Closed
- is related to
-
SERVER-27358 Socket::connect expects _timeout field to be in milliseconds
- Closed