From e14222778052e3cb7bdccd592d73c2a1aba9f23a Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 17 Aug 2016 17:58:52 +0300 Subject: [PATCH] possible fix for concurent map access in smg_event --- agents/dmtagent.go | 2 +- cache2go/lruttl.go | 11 +++++++++-- cache2go/lruttl_test.go | 2 +- sessionmanager/smg_event.go | 10 +++++++++- utils/map.go | 6 +++--- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/agents/dmtagent.go b/agents/dmtagent.go index cc6c8bcea..b0346cba8 100644 --- a/agents/dmtagent.go +++ b/agents/dmtagent.go @@ -140,7 +140,7 @@ func (self DiameterAgent) processCCR(ccr *CCR, reqProcessor *config.DARequestPro if ccr.CCRequestType == 3 { err = self.smg.Call("SMGenericV1.TerminateSession", smgEv, &rpl) } else if ccr.CCRequestType == 4 { - err = self.smg.Call("SMGenericV1.ChargeEvent", smgEv, &maxUsage) + err = self.smg.Call("SMGenericV1.ChargeEvent", smgEv.Clone(), &maxUsage) if maxUsage == 0 { smgEv[utils.USAGE] = 0 // For CDR not to debit } diff --git a/cache2go/lruttl.go b/cache2go/lruttl.go index d96b81776..99e64d459 100644 --- a/cache2go/lruttl.go +++ b/cache2go/lruttl.go @@ -2,8 +2,11 @@ package cache2go import ( "container/list" + "fmt" "sync" "time" + + "github.com/cgrates/cgrates/utils" ) // Cache is an LRU cache. It is not safe for concurrent access. @@ -151,8 +154,12 @@ func (c *Cache) removeElement(e *list.Element) { } } } - kv := e.Value.(*entry) - delete(c.cache, kv.key) + if e.Value != nil { + kv := e.Value.(*entry) + delete(c.cache, kv.key) + } else { + utils.Logger.Debug(fmt.Sprintf(": nil element: %+v", e)) + } } // Len returns the number of items in the cache. diff --git a/cache2go/lruttl_test.go b/cache2go/lruttl_test.go index 22981473d..773f13c9b 100644 --- a/cache2go/lruttl_test.go +++ b/cache2go/lruttl_test.go @@ -29,7 +29,7 @@ func TestCacheExpire(t *testing.T) { if !ok || b == nil || b != a { t.Error("Error retriving data from cache", b) } - time.Sleep(5 * time.Millisecond) + time.Sleep(10 * time.Millisecond) b, ok = cache.Get("mama") if ok || b != nil { t.Error("Error expiring data from cache", b) diff --git a/sessionmanager/smg_event.go b/sessionmanager/smg_event.go index 2d6f7855f..514b7b6d7 100644 --- a/sessionmanager/smg_event.go +++ b/sessionmanager/smg_event.go @@ -429,7 +429,7 @@ func (self SMGenericEvent) AsLcrRequest() *engine.LcrRequest { // AsMapStringString Converts into map[string]string, used for example as pubsub event func (self SMGenericEvent) AsMapStringString() (map[string]string, error) { - mp := make(map[string]string) + mp := make(map[string]string, len(self)) for k, v := range self { if strV, casts := utils.CastIfToString(v); !casts { return nil, fmt.Errorf("Value %+v does not cast to string", v) @@ -439,3 +439,11 @@ func (self SMGenericEvent) AsMapStringString() (map[string]string, error) { } return mp, nil } + +func (self SMGenericEvent) Clone() SMGenericEvent { + evOut := make(SMGenericEvent, len(self)) + for key, val := range self { + evOut[key] = val + } + return evOut +} diff --git a/utils/map.go b/utils/map.go index 7f68897f7..aa80a67e5 100644 --- a/utils/map.go +++ b/utils/map.go @@ -30,12 +30,12 @@ func ConvertMapValStrIf(inMap map[string]string) map[string]interface{} { } // Mirrors key/val -func MirrorMap(mapIn map[string]string) (map[string]string, error) { - mapOut := make(map[string]string) +func MirrorMap(mapIn map[string]string) map[string]string { + mapOut := make(map[string]string, len(mapIn)) for key, val := range mapIn { mapOut[val] = key } - return mapOut, nil + return mapOut } // Returns mising keys in a map