22
// the goroutine starts, which makes it possible for the goroutine to call
23
// Done() on itself (maybe indirectly) without a race condition.
24
>
func NewHandle(ctx context.Context) *Handle {
goro.go
25
>
ctx, cancel := context.WithCancel(ctx)
26
>
return &Handle{
27
>
context: ctx,
28
>
cancel: cancel,
29
>
done: make(chan struct{}),
30
>
}
31
>
}
32
33
// Go launches the supplied function in its own goroutine. Go should be called
34
// exactly once on each *Handle.
35
>
func (h *Handle) Go(f func(context.Context) error) *Handle {
goro.go
36
>
go func() {
37
>
// use defer here so that the channel is closed even if the func calls
38
>
// runtime.Goexit()
39
>
defer close(h.done)
40
>
if err := f(h.context); err != nil {
41
h.err.Store(err)
42
}
43
}()
45
}
46