Skip to content

Commit

Permalink
transport: hide Stream string when stored in context
Browse files Browse the repository at this point in the history
It is not thread-safe to call context.String() on any context with a
stream value since valueCtx will use %#v to access all of the Stream
fields without holding a lock. Instead, use "<nil>" as the GoString.
  • Loading branch information
Anthony Romano committed Apr 5, 2017
1 parent ee8ed34 commit 1c36b70
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions transport/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,16 +341,22 @@ func (s *Stream) Read(p []byte) (n int, err error) {
// The key to save transport.Stream in the context.
type streamKey struct{}

// streamCtxGoStringer implements the GoStringer interface for Stream
// so that ctx.String() is thread-safe by hiding the stream information.
type streamCtxGoStringer Stream

func (ss *streamCtxGoStringer) GoString() string { return "<nil>" }

// newContextWithStream creates a new context from ctx and attaches stream
// to it.
func newContextWithStream(ctx context.Context, stream *Stream) context.Context {
return context.WithValue(ctx, streamKey{}, stream)
return context.WithValue(ctx, streamKey{}, (*streamCtxGoStringer)(stream))
}

// StreamFromContext returns the stream saved in ctx.
func StreamFromContext(ctx context.Context) (s *Stream, ok bool) {
s, ok = ctx.Value(streamKey{}).(*Stream)
return
func StreamFromContext(ctx context.Context) (*Stream, bool) {
s, ok := ctx.Value(streamKey{}).(*streamCtxGoStringer)
return (*Stream)(s), ok
}

// state of transport
Expand Down

0 comments on commit 1c36b70

Please sign in to comment.