Skip to content

Commit 9afd8b4

Browse files
committed
Fix: make ishell context values safe to use concurrently
1 parent 4f77a91 commit 9afd8b4

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

context.go

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package ishell
22

3+
import "sync"
4+
35
// Context is an ishell context. It embeds ishell.Actions.
46
type Context struct {
5-
contextValues
7+
*contextValues
68
progressBar ProgressBar
79
err error
810

@@ -30,32 +32,44 @@ func (c *Context) ProgressBar() ProgressBar {
3032
}
3133

3234
// contextValues is the map for values in the context.
33-
type contextValues map[string]interface{}
35+
type contextValues struct {
36+
vals map[string]interface{}
37+
*sync.RWMutex
38+
}
3439

3540
// Get returns the value associated with this context for key, or nil
3641
// if no value is associated with key. Successive calls to Get with
3742
// the same key returns the same result.
38-
func (c contextValues) Get(key string) interface{} {
39-
return c[key]
43+
func (c *contextValues) Get(key string) interface{} {
44+
c.RLock()
45+
defer c.RUnlock()
46+
return c.vals[key]
4047
}
4148

4249
// Set sets the key in this context to value.
4350
func (c *contextValues) Set(key string, value interface{}) {
44-
if *c == nil {
45-
*c = make(map[string]interface{})
51+
if c.vals == nil {
52+
c.vals = make(map[string]interface{})
53+
c.RWMutex = &sync.RWMutex{}
4654
}
47-
(*c)[key] = value
55+
c.Lock()
56+
c.vals[key] = value
57+
c.Unlock()
4858
}
4959

5060
// Del deletes key and its value in this context.
51-
func (c contextValues) Del(key string) {
52-
delete(c, key)
61+
func (c *contextValues) Del(key string) {
62+
c.Lock()
63+
delete(c.vals, key)
64+
c.Unlock()
5365
}
5466

5567
// Keys returns all keys in the context.
56-
func (c contextValues) Keys() (keys []string) {
57-
for key := range c {
68+
func (c *contextValues) Keys() (keys []string) {
69+
c.RLock()
70+
for key := range c.vals {
5871
keys = append(keys, key)
5972
}
73+
c.RUnlock()
6074
return
6175
}

ishell.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,10 @@ func newContext(s *Shell, cmd *Cmd, args []string) *Context {
669669
Args: args,
670670
RawArgs: s.rawArgs,
671671
Cmd: *cmd,
672-
contextValues: func() contextValues {
673-
values := contextValues{}
674-
for k := range s.contextValues {
675-
values[k] = s.contextValues[k]
672+
contextValues: func() *contextValues {
673+
values := &contextValues{}
674+
for k := range s.contextValues.vals {
675+
values.Set(k, s.contextValues.vals[k])
676676
}
677677
return values
678678
}(),

0 commit comments

Comments
 (0)