14
14
#define LLVM_SOURCEKIT_CORE_CONTEXT_H
15
15
16
16
#include " SourceKit/Core/LLVM.h"
17
- #include " llvm/ADT/StringRef.h"
17
+ #include " SourceKit/Support/CancellationToken.h"
18
+ #include " SourceKit/Support/Concurrency.h"
18
19
#include " llvm/ADT/STLExtras.h"
20
+ #include " llvm/ADT/StringRef.h"
19
21
#include " llvm/Support/Mutex.h"
22
+ #include < map>
20
23
#include < memory>
21
24
#include < string>
22
25
@@ -51,12 +54,52 @@ class GlobalConfig {
51
54
Settings::CompletionOptions getCompletionOpts () const ;
52
55
};
53
56
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
+
54
96
class Context {
55
97
std::string RuntimeLibPath;
56
98
std::string DiagnosticDocumentationPath;
57
99
std::unique_ptr<LangSupport> SwiftLang;
58
100
std::shared_ptr<NotificationCenter> NotificationCtr;
59
101
std::shared_ptr<GlobalConfig> Config;
102
+ std::shared_ptr<SlowRequestSimulator> SlowRequestSim;
60
103
61
104
public:
62
105
Context (StringRef RuntimeLibPath, StringRef DiagnosticDocumentationPath,
@@ -75,6 +118,10 @@ class Context {
75
118
std::shared_ptr<NotificationCenter> getNotificationCenter () { return NotificationCtr; }
76
119
77
120
std::shared_ptr<GlobalConfig> getGlobalConfiguration () { return Config; }
121
+
122
+ std::shared_ptr<SlowRequestSimulator> getSlowRequestSimulator () {
123
+ return SlowRequestSim;
124
+ }
78
125
};
79
126
80
127
} // namespace SourceKit
0 commit comments