]> Cypherpunks.ru repositories - gostls13.git/blob - test/deferfin.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / deferfin.go
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 // Test that defers do not prevent garbage collection.
8
9 package main
10
11 import (
12         "runtime"
13         "sync"
14         "sync/atomic"
15         "time"
16 )
17
18 var sink func()
19
20 func main() {
21         // Does not work with gccgo, due to partially conservative GC.
22         // Try to enable when we have fully precise GC.
23         if runtime.Compiler == "gccgo" {
24                 return
25         }
26         N := 10
27         count := int32(N)
28         var wg sync.WaitGroup
29         wg.Add(N)
30         for i := 0; i < N; i++ {
31                 go func() {
32                         defer wg.Done()
33                         v := new(string)
34                         f := func() {
35                                 if *v != "" {
36                                         panic("oops")
37                                 }
38                         }
39                         if *v != "" {
40                                 // let the compiler think f escapes
41                                 sink = f
42                         }
43                         runtime.SetFinalizer(v, func(p *string) {
44                                 atomic.AddInt32(&count, -1)
45                         })
46                         defer f()
47                 }()
48         }
49         wg.Wait()
50         for i := 0; i < 3; 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 }