func (p *Pinger) RunLoop() {
	p.mu.Lock()
	p.ctx = newContext()
	p.mu.Unlock()
	go p.run(false)
}
func (p *Pinger) RunLoop() {
	p.mu.Lock()
	p.ctx = newContext()
	p.mu.Unlock()
	go p.run(false)
}
func ( p * Pinger ) RunLoop ( ) { p . mu . Lock ( ) p . ctx = newContext ( ) p . mu . Unlock ( ) go p . run ( false ) }
// RunLoop invokes send/receive procedure repeatedly. It sends packets to all
// hosts which have already been added by AddIP() etc. and wait those responses.
// When it receives a response, it calls "receive" handler registered by
// AddHander(). After MaxRTT seconds, it calls "idle" handler, resend packets
// and wait those response. MaxRTT works as an interval time.
//
// This is a non-blocking method so immediately returns. If you want to monitor
// and stop sending packets, use Done() and Stop() methods. For example,
//
//	p.RunLoop()
//	ticker := time.NewTicker(time.Millisecond * 250)
//	select {
//	case <-p.Done():
//		if err := p.Err(); err != nil {
//			log.Fatalf("Ping failed: %v", err)
//		}
//	case <-ticker.C:
//		break
//	}
//	ticker.Stop()
//	p.Stop()
//
// For more details, please see "cmd/ping/ping.go".
RunLoop invokes send / receive procedure repeatedly . It sends packets to all hosts which have already been added by AddIP () etc . and wait those responses . When it receives a response it calls receive handler registered by AddHander () . After MaxRTT seconds it calls idle handler resend packets and wait those response . MaxRTT works as an interval time . This is a non - blocking method so immediately returns . If you want to monitor and stop sending packets use Done () and Stop () methods . For example p . RunLoop () ticker : = time . NewTicker ( time . Millisecond * 250 ) select { case < - p . Done () : if err : = p . Err () ; err ! = nil { log . Fatalf ( Ping failed : %v err ) } case < - ticker . C : break } ticker . Stop () p . Stop () For more details please see cmd / ping / ping . go .