mirror of https://github.com/gin-gonic/gin.git
Add mutex for protect Context.Keys map (#1391)
* Add mutex for protect Context.Keys map * Fix tests Co-authored-by: Nikolay Tolkachov <nik.tolkachov@gmail.com> Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
parent
67008be35f
commit
73ccfea3ba
10
context.go
10
context.go
|
@ -16,6 +16,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-contrib/sse"
|
"github.com/gin-contrib/sse"
|
||||||
|
@ -52,6 +53,9 @@ type Context struct {
|
||||||
|
|
||||||
engine *Engine
|
engine *Engine
|
||||||
|
|
||||||
|
// This mutex protect Keys map
|
||||||
|
KeysMutex *sync.RWMutex
|
||||||
|
|
||||||
// Keys is a key/value pair exclusively for the context of each request.
|
// Keys is a key/value pair exclusively for the context of each request.
|
||||||
Keys map[string]interface{}
|
Keys map[string]interface{}
|
||||||
|
|
||||||
|
@ -78,6 +82,7 @@ func (c *Context) reset() {
|
||||||
c.Params = c.Params[0:0]
|
c.Params = c.Params[0:0]
|
||||||
c.handlers = nil
|
c.handlers = nil
|
||||||
c.index = -1
|
c.index = -1
|
||||||
|
c.KeysMutex = &sync.RWMutex{}
|
||||||
c.fullPath = ""
|
c.fullPath = ""
|
||||||
c.Keys = nil
|
c.Keys = nil
|
||||||
c.Errors = c.Errors[0:0]
|
c.Errors = c.Errors[0:0]
|
||||||
|
@ -219,16 +224,21 @@ func (c *Context) Error(err error) *Error {
|
||||||
// Set is used to store a new key/value pair exclusively for this context.
|
// 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.
|
// It also lazy initializes c.Keys if it was not used previously.
|
||||||
func (c *Context) Set(key string, value interface{}) {
|
func (c *Context) Set(key string, value interface{}) {
|
||||||
|
c.KeysMutex.Lock()
|
||||||
if c.Keys == nil {
|
if c.Keys == nil {
|
||||||
c.Keys = make(map[string]interface{})
|
c.Keys = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Keys[key] = value
|
c.Keys[key] = value
|
||||||
|
c.KeysMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the value for the given key, ie: (value, true).
|
// Get returns the value for the given key, ie: (value, true).
|
||||||
// If the value does not exists it returns (nil, false)
|
// If the value does not exists it returns (nil, false)
|
||||||
func (c *Context) Get(key string) (value interface{}, exists bool) {
|
func (c *Context) Get(key string) (value interface{}, exists bool) {
|
||||||
|
c.KeysMutex.RLock()
|
||||||
value, exists = c.Keys[key]
|
value, exists = c.Keys[key]
|
||||||
|
c.KeysMutex.RUnlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
gin.go
2
gin.go
|
@ -162,7 +162,7 @@ func Default() *Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) allocateContext() *Context {
|
func (engine *Engine) allocateContext() *Context {
|
||||||
return &Context{engine: engine}
|
return &Context{engine: engine, KeysMutex: &sync.RWMutex{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delims sets template left and right delims and returns a Engine instance.
|
// Delims sets template left and right delims and returns a Engine instance.
|
||||||
|
|
Loading…
Reference in New Issue