Home | History | Annotate | Download | only in test
      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 
      9 package main
     10 
     11 import (
     12 	"runtime"
     13 	"time"
     14 )
     15 
     16 const N = 250
     17 
     18 type A struct {
     19 	b *B
     20 	n int
     21 }
     22 
     23 type B struct {
     24 	n int
     25 }
     26 
     27 var i int
     28 var nfinal int
     29 var final [N]int
     30 
     31 // the unused return is to test finalizers with return values
     32 func 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 
     41 func 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 
     50 func nofinalB(b *B) {
     51 	panic("nofinalB run")
     52 }
     53 
     54 func 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