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  }