From 76511522da5977a46eff4e7bd965f33b0714d5b8 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sun, 3 May 2020 18:11:23 +0800 Subject: [PATCH] chore: update --- context.go | 36 ++++++++++++++++++++++++++---------- gin.go | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/context.go b/context.go index a2384c0e..9bab12ac 100644 --- a/context.go +++ b/context.go @@ -53,8 +53,13 @@ type Context struct { engine *Engine + EnablekeysMutex bool + // This mutex protect Keys map - KeysMutex *sync.RWMutex + keysMutex *sync.RWMutex + + // only initial keysMutex once + once sync.Once // Keys is a key/value pair exclusively for the context of each request. Keys map[string]interface{} @@ -86,13 +91,16 @@ func (c *Context) reset() { c.Params = c.Params[0:0] c.handlers = nil c.index = -1 - c.KeysMutex = &sync.RWMutex{} + c.fullPath = "" c.Keys = nil c.Errors = c.Errors[0:0] c.Accepted = nil c.queryCache = nil c.formCache = nil + if c.EnablekeysMutex { + c.keysMutex = &sync.RWMutex{} + } } // Copy returns a copy of the current context that can be safely used outside the request's scope. @@ -228,29 +236,37 @@ 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{}) { - if c.KeysMutex == nil { - c.KeysMutex = &sync.RWMutex{} + if c.EnablekeysMutex { + if c.keysMutex == nil { + c.once.Do(func() { + c.keysMutex = &sync.RWMutex{} + }) + } + c.keysMutex.Lock() + defer c.keysMutex.Unlock() } - 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) { - if c.KeysMutex == nil { - c.KeysMutex = &sync.RWMutex{} + if c.EnablekeysMutex { + if c.keysMutex == nil { + c.once.Do(func() { + c.keysMutex = &sync.RWMutex{} + }) + } + c.keysMutex.RLock() + defer c.keysMutex.RUnlock() } - c.KeysMutex.RLock() value, exists = c.Keys[key] - c.KeysMutex.RUnlock() return } diff --git a/gin.go b/gin.go index 1c2acbc8..ab1d0a46 100644 --- a/gin.go +++ b/gin.go @@ -162,7 +162,7 @@ func Default() *Engine { } func (engine *Engine) allocateContext() *Context { - return &Context{engine: engine, KeysMutex: &sync.RWMutex{}} + return &Context{engine: engine} } // Delims sets template left and right delims and returns a Engine instance.