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,36 +158,45 @@ 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]) select {
case <-stopCh:
return
default:
udpDataCh <- u udpDataCh <- u
} else { }
}
}()
func() {
for {
select {
case u := <-udpDataCh:
process(u.size, u.payload, u.pktAddr, processor, localIP, addrUDP, name)
case <-stopCh:
return return
} }
} }
}() }()
for {
select { for _ = range udpDataCh {
case u := <-udpDataCh: // drain
process(u.size, u.payload, u.pktAddr, processor, localIP, addrUDP, name)
case <-stopCh:
stopped.Store(true)
udpconn.Close()
close(udpDataCh)
return nil
}
} }
wg.Wait()
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) {

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")