FILE / ScuroNeko/Laniakea

scene_locks.go

Исходный файл и его история в репозитории.
FILE 24040fe164649c3e4a7ef2f9d37b9747957b0cc1
Files
Laniakea/scene_locks.go
T
ScuroNeko 24040fe164
Golang lint / lint (push) Successful in 58s
Golang lint / lint (pull_request) Successful in 13m10s
(new): expand runtime APIs
(fix): harden concurrent lifecycle
(tests): add regression coverage
(doc): update v1.2 guidance
2026-08-20 11:08:45 +03:00

71 lines
1.2 KiB
Go

package laniakea
import (
"sort"
"sync"
)
type sceneLockEntry struct {
mu sync.Mutex
refs int
}
type sceneKeyLocker struct {
mu sync.Mutex
entries map[string]*sceneLockEntry
}
func (l *sceneKeyLocker) lock(keys []string) func() {
keys = uniqueSortedStrings(keys)
if len(keys) == 0 {
return func() {}
}
l.mu.Lock()
if l.entries == nil {
l.entries = make(map[string]*sceneLockEntry)
}
entries := make([]*sceneLockEntry, len(keys))
for i, key := range keys {
entry := l.entries[key]
if entry == nil {
entry = new(sceneLockEntry)
l.entries[key] = entry
}
entry.refs++
entries[i] = entry
}
l.mu.Unlock()
for _, entry := range entries {
entry.mu.Lock()
}
return func() {
for i := len(entries) - 1; i >= 0; i-- {
entries[i].mu.Unlock()
}
l.mu.Lock()
for i, key := range keys {
entries[i].refs--
if entries[i].refs == 0 {
delete(l.entries, key)
}
}
l.mu.Unlock()
}
}
func uniqueSortedStrings(values []string) []string {
sort.Strings(values)
result := values[:0]
for _, value := range values {
if value == "" || len(result) > 0 && result[len(result)-1] == value {
continue
}
result = append(result, value)
}
return result
}