Skip to content

Commit 93b00ae

Browse files
committed
Fix panic caused by sends to a closed channel
1 parent 2b62de5 commit 93b00ae

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

main.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (d *MDNSDiscovery) Stop() error {
8585

8686
// Quit handles the pluggable-discovery QUIT command
8787
func (d *MDNSDiscovery) Quit() {
88-
close(d.entriesChan)
88+
d.Stop()
8989
}
9090

9191
// StartSync handles the pluggable-discovery START_SYNC command
@@ -103,11 +103,8 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
103103
}
104104

105105
d.entriesChan = make(chan *mdns.ServiceEntry, 4)
106-
var receiver <-chan *mdns.ServiceEntry = d.entriesChan
107-
var sender chan<- *mdns.ServiceEntry = d.entriesChan
108-
109106
go func() {
110-
for entry := range receiver {
107+
for entry := range d.entriesChan {
111108
port := toDiscoveryPort(entry)
112109
key := portKey(port)
113110
if _, ok := d.portsCache.Get(key); !ok {
@@ -118,16 +115,26 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
118115
}
119116
}()
120117

118+
// We use a separate channel to consume the events received
119+
// from Query and send them over to d.entriesChan only if
120+
// it's open.
121+
// If we'd have used d.entriesChan to get the events from
122+
// Query we risk panics cause of sends to a closed channel.
123+
// Query doesn't stop right away when we call d.Stop()
124+
// neither we have to any to do it, we can only wait for it
125+
// to return.
126+
queriesChan := make(chan *mdns.ServiceEntry, 4)
121127
params := &mdns.QueryParam{
122128
Service: mdnsServiceName,
123129
Domain: "local",
124130
Timeout: discoveryInterval,
125-
Entries: sender,
131+
Entries: queriesChan,
126132
WantUnicastResponse: false,
127133
}
128134

129135
ctx, cancel := context.WithCancel(context.Background())
130136
go func() {
137+
defer close(queriesChan)
131138
for {
132139
if err := mdns.Query(params); err != nil {
133140
errorCB("mdns lookup error: " + err.Error())
@@ -139,6 +146,13 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
139146
}
140147
}
141148
}()
149+
go func() {
150+
for entry := range queriesChan {
151+
if d.entriesChan != nil {
152+
d.entriesChan <- entry
153+
}
154+
}
155+
}()
142156
d.cancelFunc = cancel
143157
return nil
144158
}

0 commit comments

Comments
 (0)