From 79f60274a0e15ac85483f5a21c9d6ce70e0ff551 Mon Sep 17 00:00:00 2001 From: moqiancong Date: Fri, 16 Jun 2017 01:26:55 +0800 Subject: [PATCH] fix cache/memory fatal error: concurrent map iteration and map write --- cache/memory.go | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/cache/memory.go b/cache/memory.go index fff2ebbb..57e868cf 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -217,26 +217,31 @@ func (bc *MemoryCache) vaccuum() { if bc.items == nil { return } - for name := range bc.items { - bc.itemExpired(name) + if keys := bc.expiredKeys(); len(keys) != 0 { + bc.clearItems(keys) } } } -// itemExpired returns true if an item is expired. -func (bc *MemoryCache) itemExpired(name string) bool { +// expiredKeys returns key list which are expired. +func (bc *MemoryCache) expiredKeys() (keys []string) { + bc.RLock() + defer bc.RUnlock() + for key, itm := range bc.items { + if itm.isExpire() { + keys = append(keys, key) + } + } + return +} + +// clearItems removes all the items which key in keys. +func (bc *MemoryCache) clearItems(keys []string) { bc.Lock() defer bc.Unlock() - - itm, ok := bc.items[name] - if !ok { - return true + for _, key := range keys { + delete(bc.items, key) } - if itm.isExpire() { - delete(bc.items, name) - return true - } - return false } func init() {