mirror of
https://github.com/taigrr/go-fastping
synced 2025-01-18 05:03:15 -08:00
Refactor run()
This commit is contained in:
parent
af91e84187
commit
8187842419
45
fastping.go
45
fastping.go
@ -86,7 +86,7 @@ type Pinger struct {
|
|||||||
seq int
|
seq int
|
||||||
// key string is IPAddr.String()
|
// key string is IPAddr.String()
|
||||||
addrs map[string]*net.IPAddr
|
addrs map[string]*net.IPAddr
|
||||||
quit chan chan<- bool
|
ctx *context
|
||||||
running bool
|
running bool
|
||||||
// Number of (nano,milli)seconds of an idle timeout. Once it passed,
|
// Number of (nano,milli)seconds of an idle timeout. Once it passed,
|
||||||
// the library calls an idle callback function. It is also used for an
|
// the library calls an idle callback function. It is also used for an
|
||||||
@ -169,7 +169,9 @@ func (p *Pinger) AddHandler(event string, handler interface{}) error {
|
|||||||
// an error value. It means it blocks until MaxRTT seconds passed. For the
|
// an error value. It means it blocks until MaxRTT seconds passed. For the
|
||||||
// purpose of sending/receiving packets over and over, use RunLoop().
|
// purpose of sending/receiving packets over and over, use RunLoop().
|
||||||
func (p *Pinger) Run() error {
|
func (p *Pinger) Run() error {
|
||||||
return p.run(true)
|
p.ctx = newContext()
|
||||||
|
p.run(true)
|
||||||
|
return p.ctx.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invode send/receive procedure repeatedly. It sends packets to all hosts which
|
// Invode send/receive procedure repeatedly. It sends packets to all hosts which
|
||||||
@ -194,34 +196,35 @@ func (p *Pinger) Run() error {
|
|||||||
//
|
//
|
||||||
// For more detail, please see "cmd/ping/ping.go".
|
// For more detail, please see "cmd/ping/ping.go".
|
||||||
func (p *Pinger) RunLoop() <-chan error {
|
func (p *Pinger) RunLoop() <-chan error {
|
||||||
p.quit = make(chan chan<- bool)
|
p.ctx = newContext()
|
||||||
errch := make(chan error)
|
errch := make(chan error)
|
||||||
go func(ch chan<- error) {
|
go func(ch chan<- error) {
|
||||||
err := p.run(false)
|
p.run(false)
|
||||||
if err != nil {
|
if p.ctx.err != nil {
|
||||||
ch <- err
|
ch <- p.ctx.err
|
||||||
}
|
}
|
||||||
}(errch)
|
}(errch)
|
||||||
return errch
|
return errch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pinger) Stop() {
|
func (p *Pinger) Stop() {
|
||||||
if p.running {
|
p.debugln("Stop(): close(p.ctx.stop)")
|
||||||
wait := make(chan bool)
|
close(p.ctx.stop)
|
||||||
p.quit <- wait
|
p.debugln("Stop(): <-p.ctx.done")
|
||||||
<-wait
|
<-p.ctx.done
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pinger) run(once bool) error {
|
func (p *Pinger) run(once bool) {
|
||||||
p.debugln("Run(): Start")
|
p.debugln("Run(): Start")
|
||||||
conn, err := net.ListenIP("ip4:icmp", &net.IPAddr{IP: net.IPv4zero})
|
conn, err := net.ListenIP("ip4:icmp", &net.IPAddr{IP: net.IPv4zero})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
p.ctx.err = err
|
||||||
|
p.debugln("Run(): close(p.ctx.done)")
|
||||||
|
close(p.ctx.done)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
var join chan<- bool
|
|
||||||
recv := make(chan *packet)
|
recv := make(chan *packet)
|
||||||
recvCtx := newContext()
|
recvCtx := newContext()
|
||||||
|
|
||||||
@ -232,13 +235,12 @@ func (p *Pinger) run(once bool) error {
|
|||||||
queue, err := p.sendICMP4(conn)
|
queue, err := p.sendICMP4(conn)
|
||||||
|
|
||||||
ticker := time.NewTicker(p.MaxRTT)
|
ticker := time.NewTicker(p.MaxRTT)
|
||||||
p.running = true
|
|
||||||
|
|
||||||
mainloop:
|
mainloop:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case join = <-p.quit:
|
case <-p.ctx.stop:
|
||||||
p.debugln("Run(): <-p.quit")
|
p.debugln("Run(): <-p.ctx.stop")
|
||||||
break mainloop
|
break mainloop
|
||||||
case <-recvCtx.done:
|
case <-recvCtx.done:
|
||||||
p.debugln("Run(): <-recvCtx.done")
|
p.debugln("Run(): <-recvCtx.done")
|
||||||
@ -261,19 +263,16 @@ mainloop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.running = false
|
|
||||||
ticker.Stop()
|
ticker.Stop()
|
||||||
|
|
||||||
p.debugln("Run(): close(recvCtx.stop)")
|
p.debugln("Run(): close(recvCtx.stop)")
|
||||||
close(recvCtx.stop)
|
close(recvCtx.stop)
|
||||||
p.debugln("Run(): <-recvCtx.done")
|
p.debugln("Run(): <-recvCtx.done")
|
||||||
<-recvCtx.done
|
<-recvCtx.done
|
||||||
if !once {
|
p.ctx.err = err
|
||||||
p.debugln("Run(): join <- true")
|
p.debugln("Run(): close(p.ctx.done)")
|
||||||
join <- true
|
close(p.ctx.done)
|
||||||
}
|
|
||||||
p.debugln("Run(): End")
|
p.debugln("Run(): End")
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pinger) sendICMP4(conn *net.IPConn) (map[string]*net.IPAddr, error) {
|
func (p *Pinger) sendICMP4(conn *net.IPConn) (map[string]*net.IPAddr, error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user