1
1
// This module defines the Context type, which carries deadlines, cancellation signals,
2
2
// and other request-scoped values across API boundaries and between processes.
3
- // Based off : https://github.com/golang/go/tree/master/src/context
3
+ // Based on : https://github.com/golang/go/tree/master/src/context
4
4
// Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2
5
5
module context
6
6
7
7
import rand
8
8
import sync
9
9
import time
10
10
11
+ pub type CancelFn = fn ()
12
+
11
13
pub interface Canceler {
12
14
id string
13
15
cancel (remove_from_parent bool , err IError)
14
16
done () chan int
15
17
}
16
18
19
+ [deprecated ]
17
20
pub fn cancel (ctx Context) {
18
21
match mut ctx {
19
22
CancelContext {
44
47
//
45
48
// Canceling this context releases resources associated with it, so code should
46
49
// call cancel as soon as the operations running in this Context complete.
47
- pub fn with_cancel (parent Context) Context {
50
+ pub fn with_cancel (parent Context) ( Context, CancelFn) {
48
51
mut c := new_cancel_context (parent)
49
- propagate_cancel (parent, mut c)
50
- return Context (c)
52
+ propagate_cancel (parent, c)
53
+ return Context (c), fn [mut c] () {
54
+ c.cancel (true , canceled)
55
+ }
51
56
}
52
57
53
58
// new_cancel_context returns an initialized CancelContext.
@@ -61,7 +66,7 @@ fn new_cancel_context(parent Context) &CancelContext {
61
66
}
62
67
}
63
68
64
- pub fn (ctx CancelContext) deadline () ? time.Time {
69
+ pub fn (ctx & CancelContext) deadline () ? time.Time {
65
70
return none
66
71
}
67
72
@@ -79,14 +84,14 @@ pub fn (mut ctx CancelContext) err() IError {
79
84
return err
80
85
}
81
86
82
- pub fn (ctx CancelContext) value (key string ) ? voidptr {
87
+ pub fn (ctx & CancelContext) value (key Key ) ? Any {
83
88
if key == cancel_context_key {
84
- return voidptr ( unsafe { & ctx })
89
+ return ctx
85
90
}
86
91
return ctx.context.value (key)
87
92
}
88
93
89
- pub fn (ctx CancelContext) str () string {
94
+ pub fn (ctx & CancelContext) str () string {
90
95
return context_name (ctx.context) + '.with_cancel'
91
96
}
92
97
@@ -122,7 +127,7 @@ fn (mut ctx CancelContext) cancel(remove_from_parent bool, err IError) {
122
127
}
123
128
}
124
129
125
- fn propagate_cancel (parent Context, mut child Canceler) {
130
+ fn propagate_cancel (parent Context, child Canceler) {
126
131
done := parent.done ()
127
132
select {
128
133
_ := < - done {
@@ -132,19 +137,19 @@ fn propagate_cancel(parent Context, mut child Canceler) {
132
137
}
133
138
}
134
139
mut p := parent_cancel_context (parent) or {
135
- go fn (parent Context, mut child Canceler) {
140
+ go fn (parent Context, child Canceler) {
136
141
pdone := parent.done ()
137
142
select {
138
143
_ := < - pdone {
139
144
child.cancel (false , parent.err ())
140
145
}
141
146
}
142
- }(parent, mut child)
147
+ }(parent, child)
143
148
return
144
149
}
145
150
146
151
if p.err is none {
147
- p.children[child.id] = * child
152
+ p.children[child.id] = child
148
153
} else {
149
154
// parent has already been canceled
150
155
child.cancel (false , p.err)
@@ -157,19 +162,20 @@ fn propagate_cancel(parent Context, mut child Canceler) {
157
162
// parent.done() matches that CancelContext. (If not, the CancelContext
158
163
// has been wrapped in a custom implementation providing a
159
164
// different done channel, in which case we should not bypass it.)
160
- fn parent_cancel_context (parent Context) ? CancelContext {
165
+ fn parent_cancel_context (parent Context) ? & CancelContext {
161
166
done := parent.done ()
162
167
if done.closed {
163
168
return none
164
169
}
165
- if p_ptr := parent.value (cancel_context_key) {
166
- if ! isnil (p_ptr) {
167
- mut p := & CancelContext (p_ptr)
170
+ mut p := parent.value (cancel_context_key) ?
171
+ match mut p {
172
+ CancelContext {
168
173
pdone := p.done ()
169
174
if done == pdone {
170
- return * p
175
+ return p
171
176
}
172
177
}
178
+ else {}
173
179
}
174
180
return none
175
181
}
0 commit comments