Source file
src/runtime/mcleanup_test.go
1
2
3
4
5 package runtime_test
6
7 import (
8 "runtime"
9 "testing"
10 "unsafe"
11 )
12
13 func TestCleanup(t *testing.T) {
14 ch := make(chan bool, 1)
15 done := make(chan bool, 1)
16 want := 97531
17 go func() {
18
19
20
21 type T struct {
22 v int
23 p unsafe.Pointer
24 }
25 v := &new(T).v
26 *v = 97531
27 cleanup := func(x int) {
28 if x != want {
29 t.Errorf("cleanup %d, want %d", x, want)
30 }
31 ch <- true
32 }
33 runtime.AddCleanup(v, cleanup, 97531)
34 v = nil
35 done <- true
36 }()
37 <-done
38 runtime.GC()
39 <-ch
40 }
41
42 func TestCleanupMultiple(t *testing.T) {
43 ch := make(chan bool, 3)
44 done := make(chan bool, 1)
45 want := 97531
46 go func() {
47
48
49
50 type T struct {
51 v int
52 p unsafe.Pointer
53 }
54 v := &new(T).v
55 *v = 97531
56 cleanup := func(x int) {
57 if x != want {
58 t.Errorf("cleanup %d, want %d", x, want)
59 }
60 ch <- true
61 }
62 runtime.AddCleanup(v, cleanup, 97531)
63 runtime.AddCleanup(v, cleanup, 97531)
64 runtime.AddCleanup(v, cleanup, 97531)
65 v = nil
66 done <- true
67 }()
68 <-done
69 runtime.GC()
70 <-ch
71 <-ch
72 <-ch
73 }
74
75 func TestCleanupZeroSizedStruct(t *testing.T) {
76 type Z struct{}
77 z := new(Z)
78 runtime.AddCleanup(z, func(s string) {}, "foo")
79 }
80
81 func TestCleanupAfterFinalizer(t *testing.T) {
82 ch := make(chan int, 2)
83 done := make(chan bool, 1)
84 want := 97531
85 go func() {
86
87
88
89 type T struct {
90 v int
91 p unsafe.Pointer
92 }
93 v := &new(T).v
94 *v = 97531
95 finalizer := func(x *int) {
96 ch <- 1
97 }
98 cleanup := func(x int) {
99 if x != want {
100 t.Errorf("cleanup %d, want %d", x, want)
101 }
102 ch <- 2
103 }
104 runtime.AddCleanup(v, cleanup, 97531)
105 runtime.SetFinalizer(v, finalizer)
106 v = nil
107 done <- true
108 }()
109 <-done
110 runtime.GC()
111 var result int
112 result = <-ch
113 if result != 1 {
114 t.Errorf("result %d, want 1", result)
115 }
116 runtime.GC()
117 result = <-ch
118 if result != 2 {
119 t.Errorf("result %d, want 2", result)
120 }
121 }
122
123 func TestCleanupInteriorPointer(t *testing.T) {
124 ch := make(chan bool, 3)
125 done := make(chan bool, 1)
126 want := 97531
127 go func() {
128
129
130
131 type T struct {
132 p unsafe.Pointer
133 i int
134 a int
135 b int
136 c int
137 }
138 ts := new(T)
139 ts.a = 97531
140 ts.b = 97531
141 ts.c = 97531
142 cleanup := func(x int) {
143 if x != want {
144 t.Errorf("cleanup %d, want %d", x, want)
145 }
146 ch <- true
147 }
148 runtime.AddCleanup(&ts.a, cleanup, 97531)
149 runtime.AddCleanup(&ts.b, cleanup, 97531)
150 runtime.AddCleanup(&ts.c, cleanup, 97531)
151 ts = nil
152 done <- true
153 }()
154 <-done
155 runtime.GC()
156 <-ch
157 <-ch
158 <-ch
159 }
160
161 func TestCleanupStop(t *testing.T) {
162 done := make(chan bool, 1)
163 go func() {
164
165
166
167 type T struct {
168 v int
169 p unsafe.Pointer
170 }
171 v := &new(T).v
172 *v = 97531
173 cleanup := func(x int) {
174 t.Error("cleanup called, want no cleanup called")
175 }
176 c := runtime.AddCleanup(v, cleanup, 97531)
177 c.Stop()
178 v = nil
179 done <- true
180 }()
181 <-done
182 runtime.GC()
183 }
184
185 func TestCleanupStopMultiple(t *testing.T) {
186 done := make(chan bool, 1)
187 go func() {
188
189
190
191 type T struct {
192 v int
193 p unsafe.Pointer
194 }
195 v := &new(T).v
196 *v = 97531
197 cleanup := func(x int) {
198 t.Error("cleanup called, want no cleanup called")
199 }
200 c := runtime.AddCleanup(v, cleanup, 97531)
201 c.Stop()
202 c.Stop()
203 c.Stop()
204 v = nil
205 done <- true
206 }()
207 <-done
208 runtime.GC()
209 }
210
211 func TestCleanupStopinterleavedMultiple(t *testing.T) {
212 ch := make(chan bool, 3)
213 done := make(chan bool, 1)
214 go func() {
215
216
217
218 type T struct {
219 v int
220 p unsafe.Pointer
221 }
222 v := &new(T).v
223 *v = 97531
224 cleanup := func(x int) {
225 if x != 1 {
226 t.Error("cleanup called, want no cleanup called")
227 }
228 ch <- true
229 }
230 runtime.AddCleanup(v, cleanup, 1)
231 runtime.AddCleanup(v, cleanup, 2).Stop()
232 runtime.AddCleanup(v, cleanup, 1)
233 runtime.AddCleanup(v, cleanup, 2).Stop()
234 runtime.AddCleanup(v, cleanup, 1)
235 v = nil
236 done <- true
237 }()
238 <-done
239 runtime.GC()
240 <-ch
241 <-ch
242 <-ch
243 }
244
245 func TestCleanupStopAfterCleanupRuns(t *testing.T) {
246 ch := make(chan bool, 1)
247 done := make(chan bool, 1)
248 var stop func()
249 go func() {
250
251
252
253 type T struct {
254 v int
255 p unsafe.Pointer
256 }
257 v := &new(T).v
258 *v = 97531
259 cleanup := func(x int) {
260 ch <- true
261 }
262 cl := runtime.AddCleanup(v, cleanup, 97531)
263 v = nil
264 stop = cl.Stop
265 done <- true
266 }()
267 <-done
268 runtime.GC()
269 <-ch
270 stop()
271 }
272
View as plain text