Skip to content

Commit 5bdd928

Browse files
authored
Merge pull request #3 from charmbracelet/merge-upstream
2 parents 483d43d + 32c90e1 commit 5bdd928

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

context.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ type Context interface {
9393

9494
type sshContext struct {
9595
context.Context
96-
*sync.Mutex
96+
*sync.RWMutex
9797
}
9898

9999
func newContext(srv *Server) (*sshContext, context.CancelFunc) {
100100
innerCtx, cancel := context.WithCancel(context.Background())
101-
ctx := &sshContext{innerCtx, &sync.Mutex{}}
101+
ctx := &sshContext{innerCtx, &sync.RWMutex{}}
102102
ctx.SetValue(ContextKeyServer, srv)
103103
perms := &Permissions{&gossh.Permissions{}}
104104
ctx.SetValue(ContextKeyPermissions, perms)
@@ -120,9 +120,23 @@ func applyConnMetadata(ctx Context, conn gossh.ConnMetadata) {
120120
}
121121

122122
func (ctx *sshContext) SetValue(key, value interface{}) {
123+
ctx.RWMutex.Lock()
124+
defer ctx.RWMutex.Unlock()
123125
ctx.Context = context.WithValue(ctx.Context, key, value)
124126
}
125127

128+
func (ctx *sshContext) Value(key interface{}) interface{} {
129+
ctx.RWMutex.RLock()
130+
defer ctx.RWMutex.RUnlock()
131+
return ctx.Context.Value(key)
132+
}
133+
134+
func (ctx *sshContext) Done() <-chan struct{} {
135+
ctx.RWMutex.RLock()
136+
defer ctx.RWMutex.RUnlock()
137+
return ctx.Context.Done()
138+
}
139+
126140
func (ctx *sshContext) User() string {
127141
return ctx.Value(ContextKeyUser).(string)
128142
}

context_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,27 @@ func TestSetValue(t *testing.T) {
4545
t.Fatal(err)
4646
}
4747
}
48+
49+
func TestRaceRWIssue160(t *testing.T) {
50+
value := "foo"
51+
key := "bar"
52+
session, _, cleanup := newTestSessionWithOptions(t, &Server{
53+
Handler: func(s Session) {
54+
t.Run("test done", func(t *testing.T) {
55+
t.Parallel()
56+
go func() {
57+
s.Context().SetValue(key, value)
58+
}()
59+
go func() {
60+
select {
61+
case <-s.Context().Done():
62+
}
63+
}()
64+
})
65+
},
66+
}, nil)
67+
defer cleanup()
68+
if err := session.Run(""); err != nil {
69+
t.Fatal(err)
70+
}
71+
}

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@ go 1.12
55
require (
66
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
77
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d
8-
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect
9-
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
8+
golang.org/x/term v0.5.0 // indirect
109
)

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
66
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
77
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
88
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9-
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
10-
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9+
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
10+
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1111
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
12-
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc=
13-
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
12+
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
13+
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
1414
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
1515
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

0 commit comments

Comments
 (0)