storj.io/uplink@v1.13.0/private/storage/streams/streamupload/cancel_group.go (about) 1 // Copyright (C) 2023 Storj Labs, Inc. 2 // See LICENSE for copying information. 3 4 package streamupload 5 6 import ( 7 "context" 8 "sync" 9 ) 10 11 type cancelGroup struct { 12 mu sync.Mutex 13 wg sync.WaitGroup 14 cancel func() 15 err error 16 } 17 18 func newCancelGroup(ctx context.Context) (context.Context, *cancelGroup) { 19 ctx, cancel := context.WithCancel(ctx) 20 return ctx, &cancelGroup{cancel: cancel} 21 } 22 23 func (c *cancelGroup) Go(f func() error) { 24 c.wg.Add(1) 25 go func() { 26 defer c.wg.Done() 27 28 if err := f(); err != nil { 29 c.mu.Lock() 30 defer c.mu.Unlock() 31 32 if c.err == nil { 33 c.err = err 34 c.cancel() 35 } 36 } 37 }() 38 } 39 40 func (c *cancelGroup) Close() { 41 c.cancel() 42 c.wg.Wait() 43 } 44 45 func (c *cancelGroup) Wait() error { 46 c.wg.Wait() 47 return c.err 48 }