Skip to content

Commit c3c7983

Browse files
j2rong4cnCopilot
andauthored
perf(sync-closers): improve Close method (#1395)
Signed-off-by: j2rong4cn <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 22deb4d commit c3c7983

File tree

1 file changed

+20
-17
lines changed

1 file changed

+20
-17
lines changed

pkg/utils/io.go

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -207,31 +207,34 @@ func (c *SyncClosers) AcquireReference() bool {
207207
}
208208
newRef := ref + 1
209209
if atomic.CompareAndSwapInt32(&c.ref, ref, newRef) {
210-
log.Debugf("AcquireReference %p: %d", c, newRef)
210+
// log.Debugf("AcquireReference %p: %d", c, newRef)
211211
return true
212212
}
213213
}
214214
}
215215

216+
const closersClosed = math.MinInt16
217+
216218
func (c *SyncClosers) Close() error {
217-
for {
218-
ref := atomic.LoadInt32(&c.ref)
219-
if ref < 0 {
220-
return nil
221-
}
222-
newRef := ref - 1
223-
if newRef <= 0 {
224-
newRef = math.MinInt16
225-
}
226-
if atomic.CompareAndSwapInt32(&c.ref, ref, newRef) {
227-
log.Debugf("Close %p: %d", c, ref)
228-
if newRef > 0 {
229-
return nil
230-
}
231-
break
232-
}
219+
ref := atomic.AddInt32(&c.ref, -1)
220+
if ref > 0 {
221+
// log.Debugf("ReleaseReference %p: %d", c, ref)
222+
return nil
223+
}
224+
225+
if ref < -1 {
226+
atomic.StoreInt32(&c.ref, closersClosed)
227+
return nil
228+
}
229+
230+
// Attempt to acquire FinalClose permission.
231+
// At this point, ref must be 0 or -1. We try to atomically change it to the closersClosed state.
232+
// Only the first successful goroutine gets the cleanup permission.
233+
if !atomic.CompareAndSwapInt32(&c.ref, ref, closersClosed) {
234+
return nil
233235
}
234236

237+
// log.Debugf("FinalClose %p", c)
235238
var errs []error
236239
for _, closer := range c.closers {
237240
if closer != nil {

0 commit comments

Comments
 (0)