Skip to content

Commit 06dd1a3

Browse files
authored
Merge pull request #66 from hashicorp/fix-data-races
Fix races found with go test -race
2 parents 21c2ed3 + a68700c commit 06dd1a3

File tree

3 files changed

+23
-23
lines changed

3 files changed

+23
-23
lines changed

client.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"log"
66
"net"
77
"strings"
8-
"sync"
8+
"sync/atomic"
99
"time"
1010

1111
"github.com/miekg/dns"
@@ -102,9 +102,8 @@ type client struct {
102102
ipv4MulticastConn *net.UDPConn
103103
ipv6MulticastConn *net.UDPConn
104104

105-
closed bool
106-
closedCh chan struct{} // TODO(reddaly): This doesn't appear to be used.
107-
closeLock sync.Mutex
105+
closed int32
106+
closedCh chan struct{} // TODO(reddaly): This doesn't appear to be used.
108107
}
109108

110109
// NewClient creates a new mdns Client that can be used to query
@@ -150,13 +149,10 @@ func newClient() (*client, error) {
150149

151150
// Close is used to cleanup the client
152151
func (c *client) Close() error {
153-
c.closeLock.Lock()
154-
defer c.closeLock.Unlock()
155-
156-
if c.closed {
152+
if !atomic.CompareAndSwapInt32(&c.closed, 0, 1) {
153+
// something else already closed it
157154
return nil
158155
}
159-
c.closed = true
160156

161157
log.Printf("[INFO] mdns: Closing client %v", *c)
162158
close(c.closedCh)
@@ -326,8 +322,13 @@ func (c *client) recv(l *net.UDPConn, msgCh chan *dns.Msg) {
326322
return
327323
}
328324
buf := make([]byte, 65536)
329-
for !c.closed {
325+
for atomic.LoadInt32(&c.closed) == 0 {
330326
n, err := l.Read(buf)
327+
328+
if atomic.LoadInt32(&c.closed) == 1 {
329+
return
330+
}
331+
331332
if err != nil {
332333
log.Printf("[ERR] mdns: Failed to read packet: %v", err)
333334
continue

server.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"log"
66
"net"
77
"strings"
8-
"sync"
8+
"sync/atomic"
99

1010
"github.com/miekg/dns"
1111
)
@@ -51,9 +51,8 @@ type Server struct {
5151
ipv4List *net.UDPConn
5252
ipv6List *net.UDPConn
5353

54-
shutdown bool
55-
shutdownCh chan struct{}
56-
shutdownLock sync.Mutex
54+
shutdown int32
55+
shutdownCh chan struct{}
5756
}
5857

5958
// NewServer is used to create a new mDNS server from a config
@@ -87,13 +86,11 @@ func NewServer(config *Config) (*Server, error) {
8786

8887
// Shutdown is used to shutdown the listener
8988
func (s *Server) Shutdown() error {
90-
s.shutdownLock.Lock()
91-
defer s.shutdownLock.Unlock()
92-
93-
if s.shutdown {
89+
if !atomic.CompareAndSwapInt32(&s.shutdown, 0, 1) {
90+
// something else already closed us
9491
return nil
9592
}
96-
s.shutdown = true
93+
9794
close(s.shutdownCh)
9895

9996
if s.ipv4List != nil {
@@ -111,8 +108,9 @@ func (s *Server) recv(c *net.UDPConn) {
111108
return
112109
}
113110
buf := make([]byte, 65536)
114-
for !s.shutdown {
111+
for atomic.LoadInt32(&s.shutdown) == 0 {
115112
n, from, err := c.ReadFrom(buf)
113+
116114
if err != nil {
117115
continue
118116
}

server_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mdns
22

33
import (
4+
"sync/atomic"
45
"testing"
56
"time"
67
)
@@ -22,7 +23,7 @@ func TestServer_Lookup(t *testing.T) {
2223
defer serv.Shutdown()
2324

2425
entries := make(chan *ServiceEntry, 1)
25-
found := false
26+
var found int32 = 0
2627
go func() {
2728
select {
2829
case e := <-entries:
@@ -35,7 +36,7 @@ func TestServer_Lookup(t *testing.T) {
3536
if e.Info != "Local web server" {
3637
t.Fatalf("bad: %v", e)
3738
}
38-
found = true
39+
atomic.StoreInt32(&found, 1)
3940

4041
case <-time.After(80 * time.Millisecond):
4142
t.Fatalf("timeout")
@@ -52,7 +53,7 @@ func TestServer_Lookup(t *testing.T) {
5253
if err != nil {
5354
t.Fatalf("err: %v", err)
5455
}
55-
if !found {
56+
if atomic.LoadInt32(&found) == 0 {
5657
t.Fatalf("record not found")
5758
}
5859
}

0 commit comments

Comments
 (0)