feat: curio: simpler reservation release logic (#11900)

* simpler release logic

* oops, plus simpler

* simpler
This commit is contained in:
Andrew Jackson (Ajax) 2024-04-26 04:11:42 -05:00 committed by GitHub
parent 0f7c74e499
commit 5e1d8f661e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -461,42 +461,23 @@ func (st *Local) reportStorage(ctx context.Context) {
}
func (st *Local) Reserve(ctx context.Context, sid storiface.SectorRef, ft storiface.SectorFileType, storageIDs storiface.SectorPaths, overheadTab map[storiface.SectorFileType]int) (release func(), err error) {
ssize, err := sid.ProofType.SectorSize()
var ssize abi.SectorSize
ssize, err = sid.ProofType.SectorSize()
if err != nil {
return nil, err
}
release = func() {}
st.localLk.Lock()
var releaseCalled bool
// double release debug guard
var firstDonebuf []byte
var releaseFuncs []func()
release = func() {
for _, releaseFunc := range releaseFuncs {
releaseFunc()
}
// debug guard against double release call
if releaseCalled {
curStack := make([]byte, 20480)
curStack = curStack[:runtime.Stack(curStack, false)]
log.Errorw("double release call", "sector", sid, "fileType", ft, "prevStack", string(firstDonebuf), "curStack", string(curStack))
}
firstDonebuf = make([]byte, 20480)
firstDonebuf = firstDonebuf[:runtime.Stack(firstDonebuf, false)]
releaseCalled = true
}
cleanupOnError := func() { release() }
defer func() {
st.localLk.Unlock()
cleanupOnError()
if err != nil {
release()
release = func() {}
} else {
release = DoubleCallWrap(release)
}
}()
for _, fileType := range ft.AllSet() {
@ -531,21 +512,33 @@ func (st *Local) Reserve(ctx context.Context, sid storiface.SectorRef, ft storif
p.reserved += overhead
p.reservations[resID] = overhead
releaseFuncs = append(releaseFuncs, func() {
old_r := release
release = func() {
old_r()
st.localLk.Lock()
defer st.localLk.Unlock()
log.Debugw("reserve release", "id", id, "sector", sid, "fileType", fileType, "overhead", overhead, "reserved-before", p.reserved, "reserved-after", p.reserved-overhead)
p.reserved -= overhead
delete(p.reservations, resID)
})
}
}
// no errors, don't cleanup, caller will call release
cleanupOnError = func() {}
return
}
return release, nil
// DoubleCallWrap wraps a function to make sure it's not called twice
func DoubleCallWrap(f func()) func() {
var stack []byte
return func() {
curStack := make([]byte, 20480)
curStack = curStack[:runtime.Stack(curStack, false)]
if len(stack) > 0 {
log.Warnf("double call from:\n%s\nBut originally from:", curStack, stack)
return
}
stack = curStack
f()
}
}
func (st *Local) AcquireSector(ctx context.Context, sid storiface.SectorRef, existing storiface.SectorFileType, allocate storiface.SectorFileType, pathType storiface.PathType, op storiface.AcquireMode, opts ...storiface.AcquireOption) (storiface.SectorPaths, storiface.SectorPaths, error) {