modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/fixedbugs/issue5493.go (about)

     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  
     7  package main
     8  
     9  import (
    10  	"runtime"
    11  	"sync"
    12  	"sync/atomic"
    13  	"time"
    14  )
    15  
    16  const N = 10
    17  var count int64
    18  
    19  func run() error {
    20  	f1 := func() {}
    21  	f2 := func() {
    22  		func() {
    23  			f1()
    24  		}()
    25  	}
    26  	runtime.SetFinalizer(&f1, func(f *func()) {
    27  		atomic.AddInt64(&count, -1)
    28  	})
    29  	go f2()
    30  	return nil
    31  }
    32  
    33  func main() {
    34  	// Does not work on 32-bits, or with gccgo, due to partially
    35  	// conservative GC.
    36  	// Try to enable when we have fully precise GC.
    37  	if runtime.GOARCH != "amd64" || 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