From 6b246c7fe000cd7328ec3fad2503efaeab3b5b1b Mon Sep 17 00:00:00 2001 From: Nikolay Tolkachov Date: Tue, 12 Jun 2018 14:18:41 +0300 Subject: [PATCH 1/2] Add mutex for protect Context.Keys map --- context.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/context.go b/context.go index 462357e104..1c5f978d63 100755 --- a/context.go +++ b/context.go @@ -15,6 +15,7 @@ import ( "net/url" "os" "strings" + "sync" "time" "github.com/gin-contrib/sse" @@ -49,6 +50,9 @@ type Context struct { engine *Engine + // This mutex protect Keys map + KeysMutex *sync.RWMutex + // Keys is a key/value pair exclusively for the context of each request. Keys map[string]interface{} @@ -68,6 +72,7 @@ func (c *Context) reset() { c.Params = c.Params[0:0] c.handlers = nil c.index = -1 + c.KeysMutex = &sync.RWMutex{} c.Keys = nil c.Errors = c.Errors[0:0] c.Accepted = nil @@ -180,16 +185,21 @@ func (c *Context) Error(err error) *Error { // Set is used to store a new key/value pair exclusively for this context. // It also lazy initializes c.Keys if it was not used previously. func (c *Context) Set(key string, value interface{}) { + c.KeysMutex.Lock() if c.Keys == nil { c.Keys = make(map[string]interface{}) } + c.Keys[key] = value + c.KeysMutex.Unlock() } // Get returns the value for the given key, ie: (value, true). // If the value does not exists it returns (nil, false) func (c *Context) Get(key string) (value interface{}, exists bool) { + c.KeysMutex.RLock() value, exists = c.Keys[key] + c.KeysMutex.RUnlock() return } From 5fcd2a92dad107280fd716ce7e63c086bcde1310 Mon Sep 17 00:00:00 2001 From: Nikolay Tolkachov Date: Tue, 12 Jun 2018 14:58:03 +0300 Subject: [PATCH 2/2] Fix tests --- gin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gin.go b/gin.go index b91fc2fa57..69c918ae79 100644 --- a/gin.go +++ b/gin.go @@ -152,7 +152,7 @@ func Default() *Engine { } func (engine *Engine) allocateContext() *Context { - return &Context{engine: engine} + return &Context{engine: engine, KeysMutex: &sync.RWMutex{}} } func (engine *Engine) Delims(left, right string) *Engine {