void inplace_stop_source::remove_callback()

in source/inplace_stop_token.cpp [140:171]


void inplace_stop_source::remove_callback(
    inplace_stop_callback_base* callback) noexcept {
  auto oldState = lock();

  if (callback->prevPtr_ != nullptr) {
    // Callback has not been executed yet.
    // Remove from the list.
    *callback->prevPtr_ = callback->next_;
    if (callback->next_ != nullptr) {
      callback->next_->prevPtr_ = callback->prevPtr_;
    }
    unlock(oldState);
  } else {
    auto notifyingThreadId = notifyingThreadId_;
    unlock(oldState);

    // Callback has either already been executed or is
    // currently executing on another thread.
    if (std::this_thread::get_id() == notifyingThreadId) {
      if (callback->removedDuringCallback_ != nullptr) {
        *callback->removedDuringCallback_ = true;
      }
    } else {
      // Concurrently executing on another thread.
      // Wait until the other thread finishes executing the callback.
      spin_wait spin;
      while (!callback->callbackCompleted_.load(std::memory_order_acquire)) {
        spin.wait();
      }
    }
  }
}