mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-19 07:38:57 +08:00
optimize the context rw
This commit is contained in:
parent
6ece26c7c5
commit
e766285c7d
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"
|
||||||
@ -38,6 +39,9 @@ const (
|
|||||||
|
|
||||||
const abortIndex int8 = math.MaxInt8 / 2
|
const abortIndex int8 = math.MaxInt8 / 2
|
||||||
|
|
||||||
|
// RWMutex is a optimization for Context can be safely called in multiple goroutine.
|
||||||
|
var keysRWLock sync.RWMutex = sync.RWMutex{}
|
||||||
|
|
||||||
// Context is the most important part of gin. It allows us to pass variables between middleware,
|
// Context is the most important part of gin. It allows us to pass variables between middleware,
|
||||||
// manage the flow, validate the JSON of a request and render a JSON response for example.
|
// manage the flow, validate the JSON of a request and render a JSON response for example.
|
||||||
type Context struct {
|
type Context struct {
|
||||||
@ -95,9 +99,11 @@ func (c *Context) Copy() *Context {
|
|||||||
cp.index = abortIndex
|
cp.index = abortIndex
|
||||||
cp.handlers = nil
|
cp.handlers = nil
|
||||||
cp.Keys = map[string]interface{}{}
|
cp.Keys = map[string]interface{}{}
|
||||||
|
keysRWLock.RLock()
|
||||||
for k, v := range c.Keys {
|
for k, v := range c.Keys {
|
||||||
cp.Keys[k] = v
|
cp.Keys[k] = v
|
||||||
}
|
}
|
||||||
|
keysRWLock.RUnlock()
|
||||||
paramCopy := make([]Param, len(cp.Params))
|
paramCopy := make([]Param, len(cp.Params))
|
||||||
copy(paramCopy, cp.Params)
|
copy(paramCopy, cp.Params)
|
||||||
cp.Params = paramCopy
|
cp.Params = paramCopy
|
||||||
@ -219,16 +225,20 @@ 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{}) {
|
||||||
|
keysRWLock.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
|
||||||
|
keysRWLock.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) {
|
||||||
|
keysRWLock.RLock()
|
||||||
value, exists = c.Keys[key]
|
value, exists = c.Keys[key]
|
||||||
|
keysRWLock.RUnlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user