package agent import ( "path/filepath" "sync" ) // Recovery and result-journal instances share a root but are constructed by // different call/recovery paths. Locks exist only while a path is in use; they // are not a permanent identity history and do not serialize independent files. type privateStateLock struct { mu sync.Mutex users int } var privateStateLocks = struct { sync.Mutex paths map[string]*privateStateLock }{paths: make(map[string]*privateStateLock)} func holdPrivateState(path string) (func(), error) { key, err := filepath.Abs(path) if err != nil { return nil, err } privateStateLocks.Lock() lock := privateStateLocks.paths[key] if lock == nil { lock = &privateStateLock{} privateStateLocks.paths[key] = lock } lock.users++ privateStateLocks.Unlock() lock.mu.Lock() return func() { lock.mu.Unlock() privateStateLocks.Lock() lock.users-- if lock.users == 0 { delete(privateStateLocks.paths, key) } privateStateLocks.Unlock() }, nil }