aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2010-11-02 10:58:27 -0700
committerRob Pike <r@golang.org>2010-11-02 10:58:27 -0700
commit59315fbfb5cc24fc130ed683c8be10bc659d3808 (patch)
treed8f3d9adc814bedaf993fa6f10a966563c466894
parent396228a6525b211e0c368f255724eeefef264062 (diff)
downloadgo-59315fbfb5cc24fc130ed683c8be10bc659d3808.tar.gz
go-59315fbfb5cc24fc130ed683c8be10bc659d3808.zip
netchan: fix locking bug.
There's no need to hold the client mutex when calling encode, since encode itself uses a mutex to make the writes atomic. However, we need to keep the messages ordered, so add a mutex for that purpose alone. Fixes #1244. R=rsc CC=golang-dev https://golang.org/cl/2833041
-rw-r--r--src/pkg/netchan/export.go5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/pkg/netchan/export.go b/src/pkg/netchan/export.go
index 318b865b0b..8c87ee8ce4 100644
--- a/src/pkg/netchan/export.go
+++ b/src/pkg/netchan/export.go
@@ -52,6 +52,7 @@ type expClient struct {
errored bool // client has been sent an error
seqNum int64 // sequences messages sent to client; has value of highest sent
ackNum int64 // highest sequence number acknowledged
+ seqLock sync.Mutex // guarantees messages are in sequence, only locked under mu
}
func newClient(exp *Exporter, conn net.Conn) *expClient {
@@ -171,8 +172,10 @@ func (client *expClient) serveRecv(hdr header, count int64) {
client.mu.Lock()
client.seqNum++
hdr.seqNum = client.seqNum
- err := client.encode(&hdr, payData, val.Interface())
+ client.seqLock.Lock() // guarantee ordering of messages
client.mu.Unlock()
+ err := client.encode(&hdr, payData, val.Interface())
+ client.seqLock.Unlock()
if err != nil {
expLog("error encoding client response:", err)
client.sendError(&hdr, err.String())