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

Bind ClientStrand before destroying its opCtx

    XMLWordPrintable

Details

    • Fully Compatible
    • ALL
    • v5.0
    • Service Arch 2021-06-14, Service Arch 2021-06-28
    • 144
    • 4

    Description

      We create a new opCtx to serve each client request (see here). This opCtx is later destroyed in the tail of a future-continuation constructed in ServiceStateMachine::Impl::startNewLoop (see here). The destruction of opCtx, however, may run on a thread other than the one that has the Client object attached, causing read-after-free race conditions.

      Future<void> ServiceStateMachine::Impl::processMessage() {
          ...
          _opCtx = Client::getCurrent()->makeOperationContext();
          ...
      }
      

      .getAsync([this](Status status) {
          // We may or may not have an operation context, but it should definitely be gone now.
          _opCtx.reset();
          ...
      });
      

      Similarly, the opCtx used to run a command is killed after returning from handleRequest (see here). This may also run on a thread other than the one holding the client lock, resulting in data races. We should ensure the operation is only killed on a thread that owns its corresponding client object.

      Acceptance criteria: ensure the opCtx is always killed/destructed while having its Client attached to the current thread (e.g., by binding the ClientStrand). The performance impact of the changes must also be evaluated (using sys-perf), as the change is on the critical path of command execution.

      Attachments

        Issue Links

          Activity

            People

              george.wangensteen@mongodb.com George Wangensteen
              amirsaman.memaripour@mongodb.com Amirsaman Memaripour
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: