Skip to content

Commit 1c75b86

Browse files
joeybloggsjoeybloggs
authored andcommitted
Add sync.RWMutex to context Get() Set() method for thread safety
1 parent ab51f84 commit 1c75b86

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

context.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"net"
66
"net/http"
77
"strings"
8+
"sync"
89

910
"golang.org/x/net/context"
1011
"golang.org/x/net/websocket"
@@ -60,6 +61,7 @@ type Ctx struct {
6061
formParsed bool
6162
multipartFormParsed bool
6263
parent Context
64+
m *sync.RWMutex
6365
}
6466

6567
var _ context.Context = &Ctx{}
@@ -178,17 +180,26 @@ func (c *Ctx) ParseMultipartForm(maxMemory int64) error {
178180
// Set is used to store a new key/value pair exclusivelly for thisContext.
179181
// It also lazy initializes c.Keys if it was not used previously.
180182
func (c *Ctx) Set(key string, value interface{}) {
183+
181184
if c.store == nil {
185+
c.m = new(sync.RWMutex)
186+
c.m.Lock()
182187
c.store = make(store)
188+
} else {
189+
c.m.Lock()
183190
}
191+
184192
c.store[key] = value
193+
c.m.Unlock()
185194
}
186195

187196
// Get returns the value for the given key, ie: (value, true).
188197
// If the value does not exists it returns (nil, false)
189198
func (c *Ctx) Get(key string) (value interface{}, exists bool) {
190199
if c.store != nil {
200+
c.m.RLock()
191201
value, exists = c.store[key]
202+
c.m.RUnlock()
192203
}
193204
return
194205
}

context_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"net/http"
66
"net/http/httptest"
77
"os"
8+
"sync"
89
"testing"
910

1011
. "gopkg.in/go-playground/assert.v1"
@@ -107,6 +108,7 @@ func TestContext(t *testing.T) {
107108
}
108109

109110
c.params = varParams
111+
c.m = new(sync.RWMutex)
110112
c.store = storeMap
111113
c.request = r
112114

0 commit comments

Comments
 (0)