github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/storage/stores/indexshipper/downloads/util.go (about)

     1  package downloads
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  )
     7  
     8  // mtxWithReadiness combines a mutex with readiness channel. It would acquire lock only when the channel is closed to mark it ready.
     9  type mtxWithReadiness struct {
    10  	mtx   sync.RWMutex
    11  	ready chan struct{}
    12  }
    13  
    14  func newMtxWithReadiness() *mtxWithReadiness {
    15  	return &mtxWithReadiness{
    16  		ready: make(chan struct{}),
    17  	}
    18  }
    19  
    20  func (m *mtxWithReadiness) markReady() {
    21  	close(m.ready)
    22  }
    23  
    24  func (m *mtxWithReadiness) awaitReady(ctx context.Context) error {
    25  	select {
    26  	case <-ctx.Done():
    27  		return ctx.Err()
    28  	case <-m.ready:
    29  		return nil
    30  	}
    31  }
    32  
    33  func (m *mtxWithReadiness) lock(ctx context.Context) error {
    34  	err := m.awaitReady(ctx)
    35  	if err != nil {
    36  		return err
    37  	}
    38  
    39  	m.mtx.Lock()
    40  	return nil
    41  }
    42  
    43  func (m *mtxWithReadiness) unlock() {
    44  	m.mtx.Unlock()
    45  }
    46  
    47  func (m *mtxWithReadiness) rLock(ctx context.Context) error {
    48  	err := m.awaitReady(ctx)
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	m.mtx.RLock()
    54  	return nil
    55  }
    56  
    57  func (m *mtxWithReadiness) rUnlock() {
    58  	m.mtx.RUnlock()
    59  }