package stores import ( "context" "sync" "golang.org/x/xerrors" "github.com/filecoin-project/specs-actors/actors/abi" ) type sectorLock struct { lk sync.Mutex notif *ctxCond r [FileTypes]uint w SectorFileType refs uint // access with indexLocks.lk } func (l *sectorLock) canLock(read SectorFileType, write SectorFileType) bool { for i, b := range write.All() { if b && l.r[i] > 0 { return false } } return l.w&(read|write) == 0 } func (l *sectorLock) tryLock(read SectorFileType, write SectorFileType) bool { if !l.canLock(read, write) { return false } for i, set := range read.All() { if set { l.r[i]++ } } l.w |= write return true } func (l *sectorLock) lock(ctx context.Context, read SectorFileType, write SectorFileType) error { l.lk.Lock() defer l.lk.Unlock() for { if l.tryLock(read, write) { return nil } if err := l.notif.Wait(ctx); err != nil { return err } } } func (l *sectorLock) unlock(read SectorFileType, write SectorFileType) { l.lk.Lock() defer l.lk.Unlock() for i, set := range read.All() { if set { l.r[i]-- } } l.w &= ^write l.notif.Broadcast() } type indexLocks struct { lk sync.Mutex locks map[abi.SectorID]*sectorLock } func (i *indexLocks) StorageLock(ctx context.Context, sector abi.SectorID, read SectorFileType, write SectorFileType) error { if read|write == 0 { return nil } if read|write > (1<