Currently, PinnedConnectionTaskExecutor::join returns early if the RPC requestQueue is empty. But it's possible for a request to have been popped from the queue, but for it to still be being worked on. That means it's possible for threads to be running the continuation in this: https://github.com/mongodb/mongo/blob/58a69ba924e2ca557bf1c208fed59fc948107bd0/src/mongo/executor/pinned_connection_task_executor.cpp#L283 getAsync, after join has returned. If join() returning is the only thing preventing PCTE from being destroyed, this means that continuation can read garbage data because it is using "this" after it is freed, and it can cause invariant-failures if the PCTE destructor finds that the PCTE::_mutex is being held by the thread running that continuation.
We should ensure that join waits for any in-progress requests to be done before returning. We should also consider joining the scoped task executor, and having that getAsync keep a shared_ptr to "this".