blob: be6d79b2b8e09ed623639972ac9e9f7ff9a411bb [file] [log] [blame]
Russ Coxd2cc9882012-02-16 23:50:37 -05001// run
Russ Cox33e396a2010-02-03 16:31:34 -08002
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
Rob Pike501f0b52012-02-23 18:47:26 +11007// Test basic operation of finalizers.
Russ Cox33e396a2010-02-03 16:31:34 -08008
9package main
10
Russ Cox4e28cfe2010-03-26 14:15:30 -070011import (
12 "runtime"
13 "time"
14)
Russ Cox33e396a2010-02-03 16:31:34 -080015
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
Russ Cox4e28cfe2010-03-26 14:15:30 -070031// the unused return is to test finalizers with return values
32func finalA(a *A) (unused [N]int) {
Russ Cox33e396a2010-02-03 16:31:34 -080033 if final[a.n] != 0 {
Rob Pike325cf8e2010-03-24 16:46:53 -070034 println("finalA", a.n, final[a.n])
35 panic("fail")
Russ Cox33e396a2010-02-03 16:31:34 -080036 }
37 final[a.n] = 1
Russ Cox4e28cfe2010-03-26 14:15:30 -070038 return
Russ Cox33e396a2010-02-03 16:31:34 -080039}
40
41func finalB(b *B) {
42 if final[b.n] != 1 {
Rob Pike325cf8e2010-03-24 16:46:53 -070043 println("finalB", b.n, final[b.n])
44 panic("fail")
Russ Cox33e396a2010-02-03 16:31:34 -080045 }
46 final[b.n] = 2
47 nfinal++
48}
49
Dmitriy Vyukovc14b2682011-10-06 18:42:51 +030050func nofinalB(b *B) {
51 panic("nofinalB run")
52}
53
Russ Cox33e396a2010-02-03 16:31:34 -080054func main() {
55 runtime.GOMAXPROCS(4)
56 for i = 0; i < N; i++ {
57 b := &B{i}
58 a := &A{b, i}
Dmitriy Vyukovc14b2682011-10-06 18:42:51 +030059 c := new(B)
60 runtime.SetFinalizer(c, nofinalB)
Russ Cox33e396a2010-02-03 16:31:34 -080061 runtime.SetFinalizer(b, finalB)
62 runtime.SetFinalizer(a, finalA)
Dmitriy Vyukovc14b2682011-10-06 18:42:51 +030063 runtime.SetFinalizer(c, nil)
Russ Cox33e396a2010-02-03 16:31:34 -080064 }
65 for i := 0; i < N; i++ {
66 runtime.GC()
67 runtime.Gosched()
Russ Cox00f9f0c2010-03-30 10:34:57 -070068 time.Sleep(1e6)
Dmitriy Vyukovc14b2682011-10-06 18:42:51 +030069 if nfinal >= N*8/10 {
70 break
71 }
Russ Cox33e396a2010-02-03 16:31:34 -080072 }
Russ Coxa00917c2010-03-24 19:52:07 -070073 if nfinal < N*8/10 {
Russ Cox00f9f0c2010-03-30 10:34:57 -070074 println("not enough finalizing:", nfinal, "/", N)
75 panic("fail")
Russ Cox33e396a2010-02-03 16:31:34 -080076 }
77}