Skip to content

Commit c506c3f

Browse files
committed
Merge pull request #19 from valyala/sequential-profile-sessions
Allow sequential profile sessions
2 parents 4cc2898 + 392f986 commit c506c3f

2 files changed

Lines changed: 44 additions & 13 deletions

File tree

profile.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ type profile struct {
4040
// memProfileRate holds the rate for the memory profile.
4141
memProfileRate int
4242

43-
// closers holds the cleanup functions that run after each profile
44-
closers []func()
43+
// closer holds the cleanup function that run after each profile
44+
closer func()
4545

4646
// stopped records if a call to profile.Stop has been made
4747
stopped uint32
@@ -97,15 +97,13 @@ func (p *profile) Stop() {
9797
// someone has already called close
9898
return
9999
}
100-
for _, c := range p.closers {
101-
c()
102-
}
100+
p.closer()
101+
atomic.StoreUint32(&started, 0)
103102
}
104103

105104
// Start starts a new profiling session.
106105
// The caller should call the Stop method on the value returned
107-
// to cleanly stop profiling. Start can only be called once
108-
// per program execution.
106+
// to cleanly stop profiling.
109107
func Start(options ...func(*profile)) interface {
110108
Stop()
111109
} {
@@ -140,10 +138,13 @@ func Start(options ...func(*profile)) interface {
140138
log.Printf("profile: cpu profiling enabled, %s", fn)
141139
}
142140
pprof.StartCPUProfile(f)
143-
prof.closers = append(prof.closers, func() {
141+
prof.closer = func() {
144142
pprof.StopCPUProfile()
145143
f.Close()
146-
})
144+
if !prof.quiet {
145+
log.Printf("profile: cpu profiling disabled, %s", fn)
146+
}
147+
}
147148

148149
case memMode:
149150
fn := filepath.Join(path, "mem.pprof")
@@ -156,11 +157,14 @@ func Start(options ...func(*profile)) interface {
156157
if !prof.quiet {
157158
log.Printf("profile: memory profiling enabled (rate %d), %s", runtime.MemProfileRate, fn)
158159
}
159-
prof.closers = append(prof.closers, func() {
160+
prof.closer = func() {
160161
pprof.Lookup("heap").WriteTo(f, 0)
161162
f.Close()
162163
runtime.MemProfileRate = old
163-
})
164+
if !prof.quiet {
165+
log.Printf("profile: memory profiling disabled, %s", fn)
166+
}
167+
}
164168

165169
case blockMode:
166170
fn := filepath.Join(path, "block.pprof")
@@ -172,11 +176,14 @@ func Start(options ...func(*profile)) interface {
172176
if !prof.quiet {
173177
log.Printf("profile: block profiling enabled, %s", fn)
174178
}
175-
prof.closers = append(prof.closers, func() {
179+
prof.closer = func() {
176180
pprof.Lookup("block").WriteTo(f, 0)
177181
f.Close()
178182
runtime.SetBlockProfileRate(0)
179-
})
183+
if !prof.quiet {
184+
log.Printf("profile: block profiling disabled, %s", fn)
185+
}
186+
}
180187
}
181188

182189
if !prof.noShutdownHook {

profile_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,30 @@ func main() {
131131
Stderr("could not create initial output"),
132132
Err,
133133
},
134+
}, {
135+
name: "multiple profile sessions",
136+
code: `
137+
package main
138+
139+
import "github.com/pkg/profile"
140+
141+
func main() {
142+
profile.Start(profile.CPUProfile).Stop()
143+
profile.Start(profile.MemProfile).Stop()
144+
profile.Start(profile.BlockProfile).Stop()
145+
profile.Start(profile.CPUProfile).Stop()
146+
}
147+
`,
148+
checks: []checkFn{
149+
NoStdout,
150+
Stderr("profile: cpu profiling enabled",
151+
"profile: cpu profiling disabled",
152+
"profile: memory profiling enabled",
153+
"profile: memory profiling disabled",
154+
"profile: block profiling enabled",
155+
"profile: block profiling disabled"),
156+
NoErr,
157+
},
134158
}, {
135159
name: "profile quiet",
136160
code: `

0 commit comments

Comments
 (0)