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