Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-56147

In connection PoolForHost, a thread blocked waiting for free connection may be never notified

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 4.0 Required
    • Affects Version/s: 4.0.20
    • Component/s: None
    • None
    • Fully Compatible
    • ALL
    • 184

      waitForFreeConnection() is blocked for condition variable here. To work properly, the _cv should be notified each time the `_checkedOut` is decremented.

      1. In one code path, in PoolForHost::done() `_checkedOut` is properly followed by notify, because the only call site is DBConnectionPool::release().

      Even though this is correct, it is over-optimization. It is clearer to notify near the place where condition is changed. If this is regarded as an important optimization, a comment should be added.

      2. However in DBConnectionPool::decrementEgress() the `_checkedOut` is decremented and the _cv is not notified. The call site is ScopedDbConnection::kill(). This must be fixed.

      When using ScopedDbConnection, its deletion will not trigger reusing the connection.

      A possible deadlock created by this bug may hit the ReplicaSetMonitor. In Refresher::_refreshUntilMatches() we are using the ScopedDbConnection here. If ReplicaSetMonitor is releasing a scoped connection, this will not trigger anyone waiting for it. If that was the moment RSM detected a change, the deadlock may prevent other blocked threads to take advantage of freed connection.

      This problem may not be present in v4.2 and late4r because of significant refactoring like SERVER-35688 that were impossible to backport.

            andrew.shuvalov@mongodb.com Andrew Shuvalov (Inactive)
            andrew.shuvalov@mongodb.com Andrew Shuvalov (Inactive)
            0 Vote for this issue
            3 Start watching this issue