1414#define LLVM_SOURCEKIT_CORE_CONTEXT_H
1515
1616#include " SourceKit/Core/LLVM.h"
17- #include " llvm/ADT/StringRef.h"
17+ #include " SourceKit/Support/CancellationToken.h"
18+ #include " SourceKit/Support/Concurrency.h"
1819#include " llvm/ADT/STLExtras.h"
20+ #include " llvm/ADT/StringRef.h"
1921#include " llvm/Support/Mutex.h"
22+ #include < map>
2023#include < memory>
2124#include < string>
2225
@@ -51,12 +54,52 @@ class GlobalConfig {
5154 Settings::CompletionOptions getCompletionOpts () const ;
5255};
5356
57+ class SlowRequestSimulator {
58+ std::map<SourceKitCancellationToken, std::shared_ptr<Semaphore>>
59+ InProgressRequests;
60+
61+ // / Mutex guarding \c InProgressRequests.
62+ llvm::sys::Mutex InProgressRequestsMutex;
63+
64+ public:
65+ // / Simulate that a request takes \p DurationMs to execute. While waiting that
66+ // / duration, the request can be cancelled using the \p CancellationToken.
67+ // / Returns \c true if the request waited the required duration and \c false
68+ // / if it was cancelled.
69+ bool simulateLongRequest (int64_t DurationMs,
70+ SourceKitCancellationToken CancellationToken) {
71+ auto Sema = std::make_shared<Semaphore>(0 );
72+ {
73+ llvm::sys::ScopedLock L (InProgressRequestsMutex);
74+ InProgressRequests[CancellationToken] = Sema;
75+ }
76+ bool DidTimeOut = Sema->wait (DurationMs);
77+ {
78+ llvm::sys::ScopedLock L (InProgressRequestsMutex);
79+ InProgressRequests[CancellationToken] = nullptr ;
80+ }
81+ // If we timed out, we waited the required duration. If we didn't time out,
82+ // the semaphore was cancelled.
83+ return DidTimeOut;
84+ }
85+
86+ // / Cancel a simulated long request. If the required wait duration already
87+ // / elapsed, this is a no-op.
88+ void cancel (SourceKitCancellationToken CancellationToken) {
89+ llvm::sys::ScopedLock L (InProgressRequestsMutex);
90+ if (auto InProgressSema = InProgressRequests[CancellationToken]) {
91+ InProgressSema->signal ();
92+ }
93+ }
94+ };
95+
5496class Context {
5597 std::string RuntimeLibPath;
5698 std::string DiagnosticDocumentationPath;
5799 std::unique_ptr<LangSupport> SwiftLang;
58100 std::shared_ptr<NotificationCenter> NotificationCtr;
59101 std::shared_ptr<GlobalConfig> Config;
102+ std::shared_ptr<SlowRequestSimulator> SlowRequestSim;
60103
61104public:
62105 Context (StringRef RuntimeLibPath, StringRef DiagnosticDocumentationPath,
@@ -75,6 +118,10 @@ class Context {
75118 std::shared_ptr<NotificationCenter> getNotificationCenter () { return NotificationCtr; }
76119
77120 std::shared_ptr<GlobalConfig> getGlobalConfiguration () { return Config; }
121+
122+ std::shared_ptr<SlowRequestSimulator> getSlowRequestSimulator () {
123+ return SlowRequestSim;
124+ }
78125};
79126
80127} // namespace SourceKit
0 commit comments