[SERVER-27240] ConnectBG must not close() while the background thread is active Created: 30/Nov/16  Updated: 28/May/19  Resolved: 07/Dec/16

Status: Closed
Project: Core Server
Component/s: Networking
Affects Version/s: None
Fix Version/s: 3.0.15, 3.2.12, 3.4.1, 3.5.1

Type: Bug Priority: Major - P3
Reporter: Mira Carey Assignee: Mira Carey
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Backports
Depends
Duplicate
is duplicated by SERVER-13375 don't rely on ConnectBG thread for no... Closed
Related
is related to SERVER-27358 Socket::connect expects _timeout fiel... Closed
Backwards Compatibility: Fully Compatible
Operating System: ALL
Backport Completed:
Backport Requested:
v3.4, v3.2, v3.0
Sprint: Platforms 2017-01-23
Participants:
Case:

 Description   

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.



 Comments   
Comment by Githook User [ 08/Dec/16 ]

Author:

{u'username': u'hanumantmk', u'name': u'Jason Carey', u'email': u'jcarey@argv.me'}

Message: SERVER-27240 Replace ConnectBG with poll

It's unsafe to close a socket from another thread. Also, after
returning EINTR, the connect call converts to an async call. And on
non-linux systems that requires a fallback to poll/select to handle
errors.

Because of that, let's just do the connect without the background thread
at all, starting off with poll.

(cherry picked from commit a1baabeee5694aa8c4ffa1827233684d6c7fcc49)
Branch: v3.0
https://github.com/mongodb/mongo/commit/80775cd49db61ec792313da630158a2904faa75f

Comment by Githook User [ 08/Dec/16 ]

Author:

{u'username': u'hanumantmk', u'name': u'Jason Carey', u'email': u'jcarey@argv.me'}

Message: SERVER-27240 Replace ConnectBG with poll

It's unsafe to close a socket from another thread. Also, after
returning EINTR, the connect call converts to an async call. And on
non-linux systems that requires a fallback to poll/select to handle
errors.

Because of that, let's just do the connect without the background thread
at all, starting off with poll.

(cherry picked from commit a1baabeee5694aa8c4ffa1827233684d6c7fcc49)
Branch: v3.2
https://github.com/mongodb/mongo/commit/30e9f786ee94166adc1b6b3ba98b672d47604f95

Comment by Githook User [ 08/Dec/16 ]

Author:

{u'username': u'hanumantmk', u'name': u'Jason Carey', u'email': u'jcarey@argv.me'}

Message: SERVER-27240 Replace ConnectBG with poll

It's unsafe to close a socket from another thread. Also, after
returning EINTR, the connect call converts to an async call. And on
non-linux systems that requires a fallback to poll/select to handle
errors.

Because of that, let's just do the connect without the background thread
at all, starting off with poll.

(cherry picked from commit a1baabeee5694aa8c4ffa1827233684d6c7fcc49)
Branch: v3.4
https://github.com/mongodb/mongo/commit/e4113518e7b0f9dcdfe582d91f4f00dcc0589661

Comment by Githook User [ 07/Dec/16 ]

Author:

{u'username': u'hanumantmk', u'name': u'Jason Carey', u'email': u'jcarey@argv.me'}

Message: SERVER-27240 Replace ConnectBG with poll

It's unsafe to close a socket from another thread. Also, after
returning EINTR, the connect call converts to an async call. And on
non-linux systems that requires a fallback to poll/select to handle
errors.

Because of that, let's just do the connect without the background thread
at all, starting off with poll.
Branch: master
https://github.com/mongodb/mongo/commit/a1baabeee5694aa8c4ffa1827233684d6c7fcc49

Generated at Thu Feb 08 04:14:34 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.