Mercurial > hg > CbC > CbC_llvm
comparison clang-tools-extra/clangd/support/Cancellation.h @ 173:0572611fdcc8 llvm10 llvm12
reorgnization done
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 11:55:54 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
172:9fbae9c8bf63 | 173:0572611fdcc8 |
---|---|
1 //===--- Cancellation.h -------------------------------------------*-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 // Cancellation mechanism for long-running tasks. | |
9 // | |
10 // This manages interactions between: | |
11 // | |
12 // 1. Client code that starts some long-running work, and maybe cancels later. | |
13 // | |
14 // std::pair<Context, Canceler> Task = cancelableTask(); | |
15 // { | |
16 // WithContext Cancelable(std::move(Task.first)); | |
17 // Expected | |
18 // deepThoughtAsync([](int answer){ errs() << answer; }); | |
19 // } | |
20 // // ...some time later... | |
21 // if (User.fellAsleep()) | |
22 // Task.second(); | |
23 // | |
24 // (This example has an asynchronous computation, but synchronous examples | |
25 // work similarly - the Canceler should be invoked from another thread). | |
26 // | |
27 // 2. Library code that executes long-running work, and can exit early if the | |
28 // result is not needed. | |
29 // | |
30 // void deepThoughtAsync(std::function<void(int)> Callback) { | |
31 // runAsync([Callback]{ | |
32 // int A = ponder(6); | |
33 // if (isCancelled()) | |
34 // return; | |
35 // int B = ponder(9); | |
36 // if (isCancelled()) | |
37 // return; | |
38 // Callback(A * B); | |
39 // }); | |
40 // } | |
41 // | |
42 // (A real example may invoke the callback with an error on cancellation, | |
43 // the CancelledError is provided for this purpose). | |
44 // | |
45 // Cancellation has some caveats: | |
46 // - the work will only stop when/if the library code next checks for it. | |
47 // Code outside clangd such as Sema will not do this. | |
48 // - it's inherently racy: client code must be prepared to accept results | |
49 // even after requesting cancellation. | |
50 // - it's Context-based, so async work must be dispatched to threads in | |
51 // ways that preserve the context. (Like runAsync() or TUScheduler). | |
52 // | |
53 // FIXME: We could add timestamps to isCancelled() and CancelledError. | |
54 // Measuring the start -> cancel -> acknowledge -> finish timeline would | |
55 // help find where libraries' cancellation should be improved. | |
56 | |
57 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_CANCELLATION_H | |
58 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_CANCELLATION_H | |
59 | |
60 #include "support/Context.h" | |
61 #include "llvm/Support/Error.h" | |
62 #include <functional> | |
63 #include <system_error> | |
64 | |
65 namespace clang { | |
66 namespace clangd { | |
67 | |
68 /// A canceller requests cancellation of a task, when called. | |
69 /// Calling it again has no effect. | |
70 using Canceler = std::function<void()>; | |
71 | |
72 /// Defines a new task whose cancellation may be requested. | |
73 /// The returned Context defines the scope of the task. | |
74 /// When the context is active, isCancelled() is 0 until the Canceler is | |
75 /// invoked, and equal to Reason afterwards. | |
76 /// Conventionally, Reason may be the LSP error code to return. | |
77 std::pair<Context, Canceler> cancelableTask(int Reason = 1); | |
78 | |
79 /// If the current context is within a cancelled task, returns the reason. | |
80 /// (If the context is within multiple nested tasks, true if any are cancelled). | |
81 /// Always zero if there is no active cancelable task. | |
82 /// This isn't free (context lookup) - don't call it in a tight loop. | |
83 int isCancelled(const Context &Ctx = Context::current()); | |
84 | |
85 /// Conventional error when no result is returned due to cancellation. | |
86 class CancelledError : public llvm::ErrorInfo<CancelledError> { | |
87 public: | |
88 static char ID; | |
89 const int Reason; | |
90 | |
91 CancelledError(int Reason) : Reason(Reason) {} | |
92 | |
93 void log(llvm::raw_ostream &OS) const override { | |
94 OS << "Task was cancelled."; | |
95 } | |
96 std::error_code convertToErrorCode() const override { | |
97 return std::make_error_code(std::errc::operation_canceled); | |
98 } | |
99 }; | |
100 | |
101 } // namespace clangd | |
102 } // namespace clang | |
103 | |
104 #endif |