Skip to content

Commit

Permalink
examples: fix concurrent map accesses in route_guide server (grpc#1752)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfawley authored Dec 18, 2017
1 parent 4e393e0 commit 45088c2
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions examples/route_guide/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"log"
"math"
"net"
"sync"
"time"

"golang.org/x/net/context"
Expand All @@ -55,8 +56,10 @@ var (
)

type routeGuideServer struct {
savedFeatures []*pb.Feature
routeNotes map[string][]*pb.RouteNote
savedFeatures []*pb.Feature // read-only after initialized

mu sync.Mutex // protects routeNotes
routeNotes map[string][]*pb.RouteNote
}

// GetFeature returns the feature at the given point.
Expand Down Expand Up @@ -130,12 +133,17 @@ func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error
return err
}
key := serialize(in.Location)
if _, present := s.routeNotes[key]; !present {
s.routeNotes[key] = []*pb.RouteNote{in}
} else {
s.routeNotes[key] = append(s.routeNotes[key], in)
}
for _, note := range s.routeNotes[key] {

s.mu.Lock()
s.routeNotes[key] = append(s.routeNotes[key], in)
// Note: this copy prevents blocking other clients while serving this one.
// We don't need to do a deep copy, because elements in the slice are
// insert-only and never modified.
rn := make([]*pb.RouteNote, len(s.routeNotes[key]))
copy(rn, s.routeNotes[key])
s.mu.Unlock()

for _, note := range rn {
if err := stream.Send(note); err != nil {
return err
}
Expand Down Expand Up @@ -201,9 +209,8 @@ func serialize(point *pb.Point) string {
}

func newServer() *routeGuideServer {
s := new(routeGuideServer)
s := &routeGuideServer{routeNotes: make(map[string][]*pb.RouteNote)}
s.loadFeatures(*jsonDBFile)
s.routeNotes = make(map[string][]*pb.RouteNote)
return s
}

Expand Down

0 comments on commit 45088c2

Please sign in to comment.