void AsyncSSLSocket::attachSSLContext(const std::shared_ptr<SSLContext>& ctx) {
  // Check to ensure we are in client mode. Changing a server's ssl
  // context doesn't make sense since clients of that server would likely
  // become confused when the server's context changes.
  DCHECK(!server_);
  DCHECK(!ctx_);
  DCHECK(ctx);
  DCHECK(ctx->getSSLCtx());
  ctx_ = ctx;

  // It's possible this could be attached before ssl_ is set up
  if (!ssl_) {
    return;
  }

  // In order to call attachSSLContext, detachSSLContext must have been
  // previously called.
  // We need to update the initial_ctx if necessary
  // The 'initial_ctx' inside an SSL* points to the context that it was created
  // with, which is also where session callbacks and servername callbacks
  // happen.
  // When we switch to a different SSL_CTX, we want to update the initial_ctx as
  // well so that any callbacks don't go to a different object
  // NOTE: this will only work if we have access to ssl_ internals, so it may
  // not work on
  // OpenSSL version >= 1.1.0
  auto sslCtx = ctx->getSSLCtx();
  OpenSSLUtils::setSSLInitialCtx(ssl_.get(), sslCtx);
  // Detach sets the socket's context to the dummy context. Thus we must acquire
  // this lock.
  SpinLockGuard guard(dummyCtxLock);
  SSL_set_SSL_CTX(ssl_.get(), sslCtx);
}
void AsyncSSLSocket::attachSSLContext(const std::shared_ptr<SSLContext>& ctx) {
   
   
   
  DCHECK(!server_);
  DCHECK(!ctx_);
  DCHECK(ctx);
  DCHECK(ctx->getSSLCtx());
  ctx_ = ctx;

   
  if (!ssl_) {
    return;
  }

   
   
   
   
   
   
   
   
   
   
   
  auto sslCtx = ctx->getSSLCtx();
  OpenSSLUtils::setSSLInitialCtx(ssl_.get(), sslCtx);
   
   
  SpinLockGuard guard(dummyCtxLock);
  SSL_set_SSL_CTX(ssl_.get(), sslCtx);
}