Bugfix: fix closing of UDP routine (#118)

This commit is contained in:
Louis
2022-08-24 22:38:56 -05:00
committed by GitHub
parent fc42020d1b
commit d6caeaacdd
2 changed files with 30 additions and 20 deletions

View File

@@ -6,7 +6,7 @@ import (
"io" "io"
"net" "net"
"strconv" "strconv"
"sync/atomic" "sync"
"time" "time"
reuseport "github.com/libp2p/go-reuseport" reuseport "github.com/libp2p/go-reuseport"
@@ -158,37 +158,46 @@ func UDPStoppableRoutine(stopCh <-chan struct{}, name string, decodeFunc decoder
payload []byte payload []byte
} }
stopped := atomic.Value{}
stopped.Store(false)
udpDataCh := make(chan udpData) udpDataCh := make(chan udpData)
defer close(udpDataCh)
wg := &sync.WaitGroup{}
wg.Add(1)
go func() { go func() {
defer wg.Done()
for { for {
u := udpData{} u := udpData{}
u.size, u.pktAddr, _ = udpconn.ReadFromUDP(payload) u.size, u.pktAddr, _ = udpconn.ReadFromUDP(payload)
if stopped.Load() == false {
if u.size == 0 { // Ignore 0 byte packets. if u.size == 0 { // Ignore 0 byte packets.
continue continue
} }
u.payload = make([]byte, u.size) u.payload = make([]byte, u.size)
copy(u.payload, payload[0:u.size]) copy(u.payload, payload[0:u.size])
udpDataCh <- u select {
} else { case <-stopCh:
return return
default:
udpDataCh <- u
} }
} }
}() }()
func() {
for { for {
select { select {
case u := <-udpDataCh: case u := <-udpDataCh:
process(u.size, u.payload, u.pktAddr, processor, localIP, addrUDP, name) process(u.size, u.payload, u.pktAddr, processor, localIP, addrUDP, name)
case <-stopCh: case <-stopCh:
stopped.Store(true) return
udpconn.Close() }
close(udpDataCh) }
}()
for _ = range udpDataCh {
// drain
}
wg.Wait()
return nil return nil
} }
}
}
func process(size int, payload []byte, pktAddr *net.UDPAddr, processor decoder.Processor, localIP string, addrUDP net.UDPAddr, name string) { func process(size int, payload []byte, pktAddr *net.UDPAddr, processor decoder.Processor, localIP string, addrUDP net.UDPAddr, name string) {
baseMessage := BaseMessage{ baseMessage := BaseMessage{

View File

@@ -53,6 +53,7 @@ func TestCancelUDPRoutine(t *testing.T) {
require.Contains(t, []string{"message 1", "message 2", "message 3"}, readMessage()) require.Contains(t, []string{"message 1", "message 2", "message 3"}, readMessage())
dp.Shutdown() dp.Shutdown()
time.Sleep(100 * time.Millisecond)
_ = sendMessage("no more messages should be processed") _ = sendMessage("no more messages should be processed")