LCOV - code coverage report
Current view: top level - clang/tools/extra/clangd - Cancellation.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 0 3 0.0 %
Date: 2018-10-20 13:21:21 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- Cancellation.h -------------------------------------------*-C++-*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : // Cancellation mechanism for long-running tasks.
      10             : //
      11             : // This manages interactions between:
      12             : //
      13             : // 1. Client code that starts some long-running work, and maybe cancels later.
      14             : //
      15             : //   std::pair<Context, Canceler> Task = cancelableTask();
      16             : //   {
      17             : //     WithContext Cancelable(std::move(Task.first));
      18             : //     Expected
      19             : //     deepThoughtAsync([](int answer){ errs() << answer; });
      20             : //   }
      21             : //   // ...some time later...
      22             : //   if (User.fellAsleep())
      23             : //     Task.second();
      24             : //
      25             : //  (This example has an asynchronous computation, but synchronous examples
      26             : //  work similarly - the Canceler should be invoked from another thread).
      27             : //
      28             : // 2. Library code that executes long-running work, and can exit early if the
      29             : //   result is not needed.
      30             : //
      31             : //   void deepThoughtAsync(std::function<void(int)> Callback) {
      32             : //     runAsync([Callback]{
      33             : //       int A = ponder(6);
      34             : //       if (isCancelled())
      35             : //         return;
      36             : //       int B = ponder(9);
      37             : //       if (isCancelled())
      38             : //         return;
      39             : //       Callback(A * B);
      40             : //     });
      41             : //   }
      42             : //
      43             : //   (A real example may invoke the callback with an error on cancellation,
      44             : //   the CancelledError is provided for this purpose).
      45             : //
      46             : // Cancellation has some caveats:
      47             : //   - the work will only stop when/if the library code next checks for it.
      48             : //     Code outside clangd such as Sema will not do this.
      49             : //   - it's inherently racy: client code must be prepared to accept results
      50             : //     even after requesting cancellation.
      51             : //   - it's Context-based, so async work must be dispatched to threads in
      52             : //     ways that preserve the context. (Like runAsync() or TUScheduler).
      53             : //
      54             : // FIXME: We could add timestamps to isCancelled() and CancelledError.
      55             : //        Measuring the start -> cancel -> acknowledge -> finish timeline would
      56             : //        help find where libraries' cancellation should be improved.
      57             : 
      58             : #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CANCELLATION_H
      59             : #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CANCELLATION_H
      60             : 
      61             : #include "Context.h"
      62             : #include "llvm/Support/Error.h"
      63             : #include <functional>
      64             : #include <system_error>
      65             : 
      66             : namespace clang {
      67             : namespace clangd {
      68             : 
      69             : /// A canceller requests cancellation of a task, when called.
      70             : /// Calling it again has no effect.
      71             : using Canceler = std::function<void()>;
      72             : 
      73             : /// Defines a new task whose cancellation may be requested.
      74             : /// The returned Context defines the scope of the task.
      75             : /// When the context is active, isCancelled() is false until the Canceler is
      76             : /// invoked, and true afterwards.
      77             : std::pair<Context, Canceler> cancelableTask();
      78             : 
      79             : /// True if the current context is within a cancelable task which was cancelled.
      80             : /// Always false if there is no active cancelable task.
      81             : /// This isn't free (context lookup) - don't call it in a tight loop.
      82             : bool isCancelled();
      83             : 
      84             : /// Conventional error when no result is returned due to cancellation.
      85             : class CancelledError : public llvm::ErrorInfo<CancelledError> {
      86             : public:
      87             :   static char ID;
      88             : 
      89           0 :   void log(llvm::raw_ostream &OS) const override {
      90           0 :     OS << "Task was cancelled.";
      91           0 :   }
      92             :   std::error_code convertToErrorCode() const override {
      93             :     return std::make_error_code(std::errc::operation_canceled);
      94             :   }
      95             : };
      96             : 
      97             : } // namespace clangd
      98             : } // namespace clang
      99             : 
     100             : #endif

Generated by: LCOV version 1.13