func (self *logRetainer) logsQueue(category string, createIfAbsent bool) *queue.Queue { isReadLocked := true self.lock.RLock() defer func() { if isReadLocked { self.lock.RUnlock() } }() q, found := self.logsByCategory[category] if !found && createIfAbsent { q = queue.New(self.queueCapacity, nil) // escalate to write lock and add q to logsByCategory self.lock.RUnlock() isReadLocked = false self.lock.Lock() defer self.lock.Unlock() // check again as we lost all locks briefly q2, found := self.logsByCategory[category] if found { q = q2 } else { self.logsByCategory[category] = q } } // Warning if you are adding new code here. We may have either a // read lock or a write lock at this point. return q }
func New(capacity int) *QueuedSet { qs := &QueuedSet{} qs.q = queue.New(capacity, qs.delete) qs.set = make(map[interface{}]int) return qs }