package core import ( "fmt" "strings" "sync" ) type connection struct { locker sync.Mutex alias string tags []string onClose map[string]func() } func (rc *connection) addTag(name, val string) { rc.locker.Lock() defer rc.locker.Unlock() prefix := name + "=" for i, tag := range rc.tags { if strings.HasPrefix(tag, prefix) { rc.tags[i] = prefix + val return } } rc.tags = append(rc.tags, prefix+val) } func (rc *connection) removeTag(name string, val string) { rc.locker.Lock() defer rc.locker.Unlock() whole := fmt.Sprintf("%s=%s", name, val) for i, tag := range rc.tags { if tag == whole { if i == 0 && len(rc.tags) == 1 { rc.tags = nil } else { lastidx := len(rc.tags) - 1 if i < lastidx { rc.tags[i] = rc.tags[lastidx] } rc.tags = rc.tags[:lastidx] } return } } } func (rc *connection) registOnCloseFunc(name string, f func()) { rc.locker.Lock() defer rc.locker.Unlock() if rc.onClose == nil { f() return } rc.onClose[name] = f } func (rc *connection) hasOnCloseFunc(name string) bool { rc.locker.Lock() defer rc.locker.Unlock() if rc.onClose == nil { return false } _, ok := rc.onClose[name] return ok } func (rc *connection) unregistOnCloseFunc(name string) (out func()) { rc.locker.Lock() defer rc.locker.Unlock() if rc.onClose == nil { return } out = rc.onClose[name] delete(rc.onClose, name) return } func (rc *connection) cleanup() { rc.locker.Lock() defer rc.locker.Unlock() cp := rc.onClose rc.onClose = nil go func() { for _, f := range cp { f() } }() }