1*ad97ccf6SSam McCall //===--- Cancellation.cpp -----------------------------------------*-C++-*-===// 2*ad97ccf6SSam McCall // 3*ad97ccf6SSam McCall // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*ad97ccf6SSam McCall // See https://llvm.org/LICENSE.txt for license information. 5*ad97ccf6SSam McCall // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*ad97ccf6SSam McCall // 7*ad97ccf6SSam McCall //===----------------------------------------------------------------------===// 8*ad97ccf6SSam McCall 9*ad97ccf6SSam McCall #include "support/Cancellation.h" 10*ad97ccf6SSam McCall #include <atomic> 11*ad97ccf6SSam McCall 12*ad97ccf6SSam McCall namespace clang { 13*ad97ccf6SSam McCall namespace clangd { 14*ad97ccf6SSam McCall 15*ad97ccf6SSam McCall char CancelledError::ID = 0; 16*ad97ccf6SSam McCall 17*ad97ccf6SSam McCall // We don't want a cancelable scope to "shadow" an enclosing one. 18*ad97ccf6SSam McCall struct CancelState { 19*ad97ccf6SSam McCall std::shared_ptr<std::atomic<int>> Cancelled; 20*ad97ccf6SSam McCall const CancelState *Parent; 21*ad97ccf6SSam McCall }; 22*ad97ccf6SSam McCall static Key<CancelState> StateKey; 23*ad97ccf6SSam McCall cancelableTask(int Reason)24*ad97ccf6SSam McCallstd::pair<Context, Canceler> cancelableTask(int Reason) { 25*ad97ccf6SSam McCall assert(Reason != 0 && "Can't detect cancellation if Reason is zero"); 26*ad97ccf6SSam McCall CancelState State; 27*ad97ccf6SSam McCall State.Cancelled = std::make_shared<std::atomic<int>>(); 28*ad97ccf6SSam McCall State.Parent = Context::current().get(StateKey); 29*ad97ccf6SSam McCall return { 30*ad97ccf6SSam McCall Context::current().derive(StateKey, State), 31*ad97ccf6SSam McCall [Reason, Flag(State.Cancelled)] { *Flag = Reason; }, 32*ad97ccf6SSam McCall }; 33*ad97ccf6SSam McCall } 34*ad97ccf6SSam McCall isCancelled(const Context & Ctx)35*ad97ccf6SSam McCallint isCancelled(const Context &Ctx) { 36*ad97ccf6SSam McCall for (const CancelState *State = Ctx.get(StateKey); State != nullptr; 37*ad97ccf6SSam McCall State = State->Parent) 38*ad97ccf6SSam McCall if (int Reason = State->Cancelled->load()) 39*ad97ccf6SSam McCall return Reason; 40*ad97ccf6SSam McCall return 0; 41*ad97ccf6SSam McCall } 42*ad97ccf6SSam McCall 43*ad97ccf6SSam McCall } // namespace clangd 44*ad97ccf6SSam McCall } // namespace clang 45