diff --git a/ping.go b/ping.go index fe51456..f2e23d1 100644 --- a/ping.go +++ b/ping.go @@ -143,6 +143,7 @@ type Pinger struct { avgRtt time.Duration stdDevRtt time.Duration stddevm2 time.Duration + statsMu sync.RWMutex // If true, keep a record of rtts of all received packets. // Set to false to avoid memory bloat for long running pings. @@ -255,7 +256,14 @@ type Statistics struct { } func (p *Pinger) updateStatistics(pkt *Packet) { + p.statsMu.Lock() + defer p.statsMu.Unlock() + p.PacketsRecv++ + if p.RecordRtts { + p.rtts = append(p.rtts, pkt.Rtt) + } + if p.PacketsRecv == 1 || pkt.Rtt < p.minRtt { p.minRtt = pkt.Rtt } @@ -451,9 +459,12 @@ func (p *Pinger) finish() { // pinger is running or after it is finished. OnFinish calls this function to // get it's finished statistics. func (p *Pinger) Statistics() *Statistics { - loss := float64(p.PacketsSent-p.PacketsRecv) / float64(p.PacketsSent) * 100 + p.statsMu.RLock() + defer p.statsMu.RUnlock() + sent := p.PacketsSent + loss := float64(sent-p.PacketsRecv) / float64(sent) * 100 s := Statistics{ - PacketsSent: p.PacketsSent, + PacketsSent: sent, PacketsRecv: p.PacketsRecv, PacketsRecvDuplicates: p.PacketsRecvDuplicates, PacketLoss: loss, @@ -582,9 +593,6 @@ func (p *Pinger) processPacket(recv *packet) error { return fmt.Errorf("invalid ICMP echo reply; type: '%T', '%v'", pkt, pkt) } - if p.RecordRtts { - p.rtts = append(p.rtts, inPkt.Rtt) - } handler := p.OnRecv if handler != nil { handler(inPkt)