On ASIOSessions where a networking baton is available and async networking is being used, opportunistic{Read,Write} attempt to add the ASIOSession to the baton's pollset via Baton::addSession when the socket operation would block. addSession returns a future that resolves with success when the socket is available for work. opportunsitc{Read,Write} functions therefore chain a continuation to the future returned by addSession that invokes themselves again recursively to work with the available socket.
Normally, at the time the continuation is chained, the socket is not ready for work, so the continuation will not be run inline as the future returned by addSession is not ready. However, if the future is ready when the continuation is chained, as might be the case if the baton has been detached, the functions will be invoked inline. Because the functions acquire _asyncOpMutex before chaining this continuation, the recursive inline invocation will deadlock attempting to re-acquire this mutex.
This deadlock may occur on a networking reactor thread as these often call asyncSourceMessage/asyncSinkMessage. Additionally, note that this deadlock will hang any other threads that subsequently try and access the _asyncOpMutex, such as client threads (via batons) attempting to cancel outstanding networking operations.
- is related to
-
SERVER-64191 Ensure `Session::cancelAsyncOperations` complies with the contract
- Closed