| // run | |
| // Copyright 2009 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // Test basic operation of finalizers. | |
| package main | |
| import ( | |
| "runtime" | |
| "time" | |
| ) | |
| const N = 250 | |
| type A struct { | |
| b *B | |
| n int | |
| } | |
| type B struct { | |
| n int | |
| } | |
| var i int | |
| var nfinal int | |
| var final [N]int | |
| // the unused return is to test finalizers with return values | |
| func finalA(a *A) (unused [N]int) { | |
| if final[a.n] != 0 { | |
| println("finalA", a.n, final[a.n]) | |
| panic("fail") | |
| } | |
| final[a.n] = 1 | |
| return | |
| } | |
| func finalB(b *B) { | |
| if final[b.n] != 1 { | |
| println("finalB", b.n, final[b.n]) | |
| panic("fail") | |
| } | |
| final[b.n] = 2 | |
| nfinal++ | |
| } | |
| func nofinalB(b *B) { | |
| panic("nofinalB run") | |
| } | |
| func main() { | |
| runtime.GOMAXPROCS(4) | |
| for i = 0; i < N; i++ { | |
| b := &B{i} | |
| a := &A{b, i} | |
| c := new(B) | |
| runtime.SetFinalizer(c, nofinalB) | |
| runtime.SetFinalizer(b, finalB) | |
| runtime.SetFinalizer(a, finalA) | |
| runtime.SetFinalizer(c, nil) | |
| } | |
| for i := 0; i < N; i++ { | |
| runtime.GC() | |
| runtime.Gosched() | |
| time.Sleep(1e6) | |
| if nfinal >= N*8/10 { | |
| break | |
| } | |
| } | |
| if nfinal < N*8/10 { | |
| println("not enough finalizing:", nfinal, "/", N) | |
| panic("fail") | |
| } | |
| } |