1// 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}
78