peer: use atomics instead of mutexes (#670)

This commit is contained in:
David Hill 2016-06-20 15:34:21 -04:00 committed by Dave Collins
parent ff4ada0b0e
commit 7de7bddba9

View file

@ -392,10 +392,12 @@ type HostToNetAddrFunc func(host string, port uint16,
// provided as a convenience. // provided as a convenience.
type Peer struct { type Peer struct {
// The following variables must only be used atomically. // The following variables must only be used atomically.
connected int32
disconnect int32
bytesReceived uint64 bytesReceived uint64
bytesSent uint64 bytesSent uint64
lastRecv int64
lastSend int64
connected int32
disconnect int32
conn net.Conn conn net.Conn
@ -429,8 +431,6 @@ type Peer struct {
statsMtx sync.RWMutex statsMtx sync.RWMutex
timeOffset int64 timeOffset int64
timeConnected time.Time timeConnected time.Time
lastSend time.Time
lastRecv time.Time
startingHeight int32 startingHeight int32
lastBlock int32 lastBlock int32
lastAnnouncedBlock *wire.ShaHash lastAnnouncedBlock *wire.ShaHash
@ -509,10 +509,10 @@ func (p *Peer) StatsSnapshot() *StatsSnap {
Addr: addr, Addr: addr,
UserAgent: userAgent, UserAgent: userAgent,
Services: services, Services: services,
LastSend: p.lastSend, LastSend: p.LastSend(),
LastRecv: p.lastRecv, LastRecv: p.LastRecv(),
BytesSent: atomic.LoadUint64(&p.bytesSent), BytesSent: p.BytesSent(),
BytesRecv: atomic.LoadUint64(&p.bytesReceived), BytesRecv: p.BytesReceived(),
ConnTime: p.timeConnected, ConnTime: p.timeConnected,
TimeOffset: p.timeOffset, TimeOffset: p.timeOffset,
Version: protocolVersion, Version: protocolVersion,
@ -667,20 +667,14 @@ func (p *Peer) LastBlock() int32 {
// //
// This function is safe for concurrent access. // This function is safe for concurrent access.
func (p *Peer) LastSend() time.Time { func (p *Peer) LastSend() time.Time {
p.statsMtx.RLock() return time.Unix(atomic.LoadInt64(&p.lastSend), 0)
defer p.statsMtx.RUnlock()
return p.lastSend
} }
// LastRecv returns the last recv time of the peer. // LastRecv returns the last recv time of the peer.
// //
// This function is safe for concurrent access. // This function is safe for concurrent access.
func (p *Peer) LastRecv() time.Time { func (p *Peer) LastRecv() time.Time {
p.statsMtx.RLock() return time.Unix(atomic.LoadInt64(&p.lastRecv), 0)
defer p.statsMtx.RUnlock()
return p.lastRecv
} }
// BytesSent returns the total number of bytes sent by the peer. // BytesSent returns the total number of bytes sent by the peer.
@ -1496,9 +1490,7 @@ out:
} }
break out break out
} }
p.statsMtx.Lock() atomic.StoreInt64(&p.lastRecv, time.Now().Unix())
p.lastRecv = time.Now()
p.statsMtx.Unlock()
p.stallControl <- stallControlMsg{sccReceiveMessage, rmsg} p.stallControl <- stallControlMsg{sccReceiveMessage, rmsg}
// Ensure version message comes first. // Ensure version message comes first.
@ -1876,9 +1868,7 @@ out:
// message that it has been sent (if requested), and // message that it has been sent (if requested), and
// signal the send queue to the deliver the next queued // signal the send queue to the deliver the next queued
// message. // message.
p.statsMtx.Lock() atomic.StoreInt64(&p.lastSend, time.Now().Unix())
p.lastSend = time.Now()
p.statsMtx.Unlock()
if msg.doneChan != nil { if msg.doneChan != nil {
msg.doneChan <- struct{}{} msg.doneChan <- struct{}{}
} }