blob: be6d79b2b8e09ed623639972ac9e9f7ff9a411bb [file] [log] [blame]
Brent Austinba3052e2015-04-21 16:08:23 -07001// run
2
3// Copyright 2009 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test basic operation of finalizers.
8
9package main
10
11import (
12 "runtime"
13 "time"
14)
15
16const N = 250
17
18type A struct {
19 b *B
20 n int
21}
22
23type B struct {
24 n int
25}
26
27var i int
28var nfinal int
29var final [N]int
30
31// the unused return is to test finalizers with return values
32func finalA(a *A) (unused [N]int) {
33 if final[a.n] != 0 {
34 println("finalA", a.n, final[a.n])
35 panic("fail")
36 }
37 final[a.n] = 1
38 return
39}
40
41func finalB(b *B) {
42 if final[b.n] != 1 {
43 println("finalB", b.n, final[b.n])
44 panic("fail")
45 }
46 final[b.n] = 2
47 nfinal++
48}
49
50func nofinalB(b *B) {
51 panic("nofinalB run")
52}
53
54func main() {
55 runtime.GOMAXPROCS(4)
56 for i = 0; i < N; i++ {
57 b := &B{i}
58 a := &A{b, i}
59 c := new(B)
60 runtime.SetFinalizer(c, nofinalB)
61 runtime.SetFinalizer(b, finalB)
62 runtime.SetFinalizer(a, finalA)
63 runtime.SetFinalizer(c, nil)
64 }
65 for i := 0; i < N; i++ {
66 runtime.GC()
67 runtime.Gosched()
68 time.Sleep(1e6)
69 if nfinal >= N*8/10 {
70 break
71 }
72 }
73 if nfinal < N*8/10 {
74 println("not enough finalizing:", nfinal, "/", N)
75 panic("fail")
76 }
77}