blob: 98e0e9b299f80612ca11dc7bbc714a5d95e92574 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
The Cancellation library
========================
Intro
-----
This small library provides primitives for implementation of a cooperative cancellation of long running or asynchronous operations.
The design has been copied from the well-known CancellationTokenSource/CancellationToken classes of the .NET Framework
To use the library include `cancellation_token.h`.
Examples
--------
1. Simple check for cancellation
```c++
void LongRunningOperation(TCancellationToken token) {
...
if (token.IsCancellationRequested()) {
return;
}
...
}
TCancellationTokenSource source;
TThread thread([token = source.Token()]() { LongRunningOperation(std::move(token)); });
thread.Start();
...
source.Cancel();
thread.Join();
```
2. Exit via an exception
```c++
void LongRunningOperation(TCancellationToken token) {
try {
for (;;) {
...
token.ThrowIfCancellationRequested();
...
}
} catch (TOperationCancelledException const&) {
return;
} catch (...) {
Y_FAIL("Never should be there")
}
}
TCancellationTokenSource source;
TThread thread([token = source.Token()]() { LongRunningOperation(std::move(token)); });
thread.Start();
...
source.Cancel();
thread.Join();
```
3. Periodic poll with cancellation
```c++
void LongRunningOperation(TCancellationToken token) {
while (!token.Wait(PollInterval)) {
...
}
}
TCancellationTokenSource source;
TThread thread([token = source.Token()]() { LongRunningOperation(std::move(token)); });
thread.Start();
...
source.Cancel();
thread.Join();
```
4. Waiting on the future
```c++
TFuture<void> InnerOperation();
TFuture<void> OuterOperation(TCancellationToken token) {
return WaitAny(FirstOperation(), token.Future())
.Apply([token = std::move(token)](auto&&) {
token.ThrowIfCancellationRequested();
});
}
TCancellationTokenSource source;
auto future = OuterOperation();
...
source.Cancel()
...
try {
auto value = future.ExtractValueSync();
} catch (TOperationCancelledException const&) {
// cancelled
}
```
5. Using default token when no cancellation needed
```c++
void LongRunningOperation(TCancellationToken token) {
...
if (token.IsCancellationRequested()) {
return;
}
...
}
// We do not want to cancel the operation. So, there is no need to create a cancellation token source
LongRunningOperation(TCancellationToken::Default);
```
|