Skip to content

Commit 2ea98d9

Browse files
committed
Merge pull request #704 from fjl/p2p-concurrency-fixups
p2p: more concurrency fixups
2 parents f6f9a0d + 0217652 commit 2ea98d9

File tree

6 files changed

+14
-41
lines changed

6 files changed

+14
-41
lines changed

p2p/discover/node.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import (
1414
"strconv"
1515
"strings"
1616
"sync"
17-
"sync/atomic"
18-
"time"
1917

2018
"github.com/ethereum/go-ethereum/crypto"
2119
"github.com/ethereum/go-ethereum/crypto/secp256k1"
@@ -31,9 +29,6 @@ type Node struct {
3129

3230
DiscPort int // UDP listening port for discovery protocol
3331
TCPPort int // TCP listening port for RLPx
34-
35-
// this must be set/read using atomic load and store.
36-
activeStamp int64
3732
}
3833

3934
func newNode(id NodeID, addr *net.UDPAddr) *Node {
@@ -50,16 +45,6 @@ func (n *Node) isValid() bool {
5045
return !n.IP.IsMulticast() && !n.IP.IsUnspecified() && n.TCPPort != 0 && n.DiscPort != 0
5146
}
5247

53-
func (n *Node) bumpActive() {
54-
stamp := time.Now().Unix()
55-
atomic.StoreInt64(&n.activeStamp, stamp)
56-
}
57-
58-
func (n *Node) active() time.Time {
59-
stamp := atomic.LoadInt64(&n.activeStamp)
60-
return time.Unix(stamp, 0)
61-
}
62-
6348
func (n *Node) addr() *net.UDPAddr {
6449
return &net.UDPAddr{IP: n.IP, Port: n.DiscPort}
6550
}

p2p/discover/table.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ outer:
326326
func (b *bucket) bump(n *Node) bool {
327327
for i := range b.entries {
328328
if b.entries[i].ID == n.ID {
329-
n.bumpActive()
330329
// move it to the front
331330
copy(b.entries[1:], b.entries[:i])
332331
b.entries[0] = n

p2p/discover/udp.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,12 @@ func (t *udp) loop() {
267267
defer timeout.Stop()
268268

269269
rearmTimeout := func() {
270-
if len(pending) == 0 || nextDeadline == pending[0].deadline {
270+
now := time.Now()
271+
if len(pending) == 0 || now.Before(nextDeadline) {
271272
return
272273
}
273274
nextDeadline = pending[0].deadline
274-
timeout.Reset(nextDeadline.Sub(time.Now()))
275+
timeout.Reset(nextDeadline.Sub(now))
275276
}
276277

277278
for {

p2p/handshake.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func setupOutboundConn(fd net.Conn, prv *ecdsa.PrivateKey, our *protoHandshake,
115115
// returning the handshake read error. If the remote side
116116
// disconnects us early with a valid reason, we should return it
117117
// as the error so it can be tracked elsewhere.
118-
werr := make(chan error)
118+
werr := make(chan error, 1)
119119
go func() { werr <- Send(rw, handshakeMsg, our) }()
120120
rhs, err := readProtocolHandshake(rw, secrets.RemoteID, our)
121121
if err != nil {

p2p/peer.go

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"errors"
55
"fmt"
66
"io"
7-
"io/ioutil"
87
"net"
98
"sort"
109
"sync"
@@ -20,8 +19,7 @@ const (
2019
baseProtocolLength = uint64(16)
2120
baseProtocolMaxMsgSize = 10 * 1024 * 1024
2221

23-
pingInterval = 15 * time.Second
24-
disconnectGracePeriod = 2 * time.Second
22+
pingInterval = 15 * time.Second
2523
)
2624

2725
const (
@@ -129,39 +127,27 @@ func (p *Peer) run() DiscReason {
129127
case err := <-readErr:
130128
if r, ok := err.(DiscReason); ok {
131129
reason = r
132-
break
130+
} else {
131+
// Note: We rely on protocols to abort if there is a write
132+
// error. It might be more robust to handle them here as well.
133+
p.DebugDetailf("Read error: %v\n", err)
134+
reason = DiscNetworkError
133135
}
134-
// Note: We rely on protocols to abort if there is a write
135-
// error. It might be more robust to handle them here as well.
136-
p.DebugDetailf("Read error: %v\n", err)
137-
p.conn.Close()
138-
reason = DiscNetworkError
139136
case err := <-p.protoErr:
140137
reason = discReasonForError(err)
141138
case reason = <-p.disc:
142139
}
143140

144141
close(p.closed)
142+
p.politeDisconnect(reason)
145143
p.wg.Wait()
146-
if reason != DiscNetworkError {
147-
p.politeDisconnect(reason)
148-
}
149144
p.Debugf("Disconnected: %v\n", reason)
150145
return reason
151146
}
152147

153148
func (p *Peer) politeDisconnect(reason DiscReason) {
154-
done := make(chan struct{})
155-
go func() {
149+
if reason != DiscNetworkError {
156150
SendItems(p.rw, discMsg, uint(reason))
157-
// Wait for the other side to close the connection.
158-
// Discard any data that they send until then.
159-
io.Copy(ioutil.Discard, p.conn)
160-
close(done)
161-
}()
162-
select {
163-
case <-done:
164-
case <-time.After(disconnectGracePeriod):
165151
}
166152
p.conn.Close()
167153
}

p2p/server.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,11 @@ func (srv *Server) Stop() {
260260
// No new peers can be added at this point because dialLoop and
261261
// listenLoop are down. It is safe to call peerWG.Wait because
262262
// peerWG.Add is not called outside of those loops.
263+
srv.lock.Lock()
263264
for _, peer := range srv.peers {
264265
peer.Disconnect(DiscQuitting)
265266
}
267+
srv.lock.Unlock()
266268
srv.peerWG.Wait()
267269
}
268270

0 commit comments

Comments
 (0)