...
Run Format

Source file test/deferfin.go

Documentation: test

  // run
  
  // Copyright 2013 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 that defers do not prevent garbage collection.
  
  package main
  
  import (
  	"runtime"
  	"sync"
  	"sync/atomic"
  	"time"
  )
  
  var sink func()
  
  func main() {
  	// Does not work on 32-bits due to partially conservative GC.
  	// Try to enable when we have fully precise GC.
  	if runtime.GOARCH != "amd64" {
  		return
  	}
  	// Likewise for gccgo.
  	if runtime.Compiler == "gccgo" {
  		return
  	}
  	N := 10
  	count := int32(N)
  	var wg sync.WaitGroup
  	wg.Add(N)
  	for i := 0; i < N; i++ {
  		go func() {
  			defer wg.Done()
  			v := new(string)
  			f := func() {
  				if *v != "" {
  					panic("oops")
  				}
  			}
  			if *v != "" {
  				// let the compiler think f escapes
  				sink = f
  			}
  			runtime.SetFinalizer(v, func(p *string) {
  				atomic.AddInt32(&count, -1)
  			})
  			defer f()
  		}()
  	}
  	wg.Wait()
  	for i := 0; i < 3; i++ {
  		time.Sleep(10 * time.Millisecond)
  		runtime.GC()
  	}
  	if count != 0 {
  		println(count, "out of", N, "finalizer are not called")
  		panic("not all finalizers are called")
  	}
  }
  
  

View as plain text