1// run 2 3// Copyright 2013 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 7package main 8 9import ( 10 "runtime" 11 "sync" 12 "sync/atomic" 13 "time" 14) 15 16const N = 10 17 18var count int64 19 20func run() error { 21 f1 := func() {} 22 f2 := func() { 23 func() { 24 f1() 25 }() 26 } 27 runtime.SetFinalizer(&f1, func(f *func()) { 28 atomic.AddInt64(&count, -1) 29 }) 30 go f2() 31 return nil 32} 33 34func main() { 35 // Does not work with gccgo, due to partially conservative GC. 36 // Try to enable when we have fully precise GC. 37 if runtime.Compiler == "gccgo" { 38 return 39 } 40 count = N 41 var wg sync.WaitGroup 42 wg.Add(N) 43 for i := 0; i < N; i++ { 44 go func() { 45 run() 46 wg.Done() 47 }() 48 } 49 wg.Wait() 50 for i := 0; i < 2*N; i++ { 51 time.Sleep(10 * time.Millisecond) 52 runtime.GC() 53 } 54 if count != 0 { 55 println(count, "out of", N, "finalizer are not called") 56 panic("not all finalizers are called") 57 } 58} 59