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 }