Skip to content

Commit 5945b7e

Browse files
committed
Multicast: detected and removed data race condition
1 parent 40be7fb commit 5945b7e

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

src/github.com/getlantern/flashlight/localdiscovery/localdiscovery.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212

1313
const (
1414
messageType = `LocalDiscovery`
15-
updatePeriod = 10
1615
)
1716

1817
var (
@@ -52,7 +51,7 @@ func Start(advertise bool, portToAdvertise string) {
5251
mc = multicast.JoinMulticast(addOrRemoveCb, addOrRemoveCb)
5352

5453
if advertise {
55-
mc.Payload = portToAdvertise
54+
mc.SetPayload(portToAdvertise)
5655
mc.StartMulticast()
5756
}
5857

src/github.com/getlantern/multicast/cmd/multicast.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func main() {
2525
log.Fatal("Error setting up socket for multicast loop")
2626
}
2727
*/
28-
mc.Period = 1
28+
mc.SetPeriod(1)
2929
mc.StartMulticast()
3030
mc.ListenPeers()
3131

src/github.com/getlantern/multicast/multicast.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@ type eventCallback func(string, []PeerInfo)
3030

3131
// Multicast servent main structure
3232
type Multicast struct {
33-
Period int // multicast period (in secs, 10 by default)
34-
Payload string // Will be appended to the messages
35-
33+
period int // multicast period (in secs, 10 by default)
34+
payload string // Will be appended to the messages
3635
conn *net.UDPConn
3736
addr *net.UDPAddr
3837
failedTime int // timeout for peers' hello messages, 0 means no timeout
@@ -85,17 +84,33 @@ func JoinMulticast(addPeerCallback eventCallback, removePeerCallback eventCallba
8584
}
8685

8786
return &Multicast{
88-
Period: defaultPeriod,
87+
period: defaultPeriod,
8988
conn: c,
9089
addr: udpAddr,
9190
failedTime: defaultFailedTime,
9291
addPeerCallback: aCb,
9392
removePeerCallback: rCb,
93+
helloTicker: time.NewTicker(time.Duration(defaultPeriod) * time.Second),
9494
quit: make(chan bool, 1),
9595
peers: make(map[string]PeerInfo),
9696
}
9797
}
9898

99+
// SetPeriod will define a different interval for the periodic multicasts. Currently setting the
100+
// period once StartMulticast has been called is not supported, so this function must be called
101+
// always before StartMulticast()
102+
func (mc *Multicast) SetPeriod(period int) {
103+
mc.period = period
104+
mc.helloTicker = time.NewTicker(time.Duration(period) * time.Second)
105+
}
106+
107+
// SetPayload will define a payload to carry with multicast messages. Currently setting the
108+
// payload once StartMulticast has been called is not supported, so this function must be called
109+
// always before StartMulticast()
110+
func (mc *Multicast) SetPayload(payload string) {
111+
mc.payload = payload
112+
}
113+
99114
// StartMulticast initiates advertising ourselves through multicasting
100115
func (mc *Multicast) StartMulticast() {
101116
// Periodically announce ourselves to the network
@@ -120,11 +135,10 @@ func (mc *Multicast) ListenPeers() {
120135
// users of this library when the program exits or the discovery service is disabled by
121136
// the end user
122137
func (mc *Multicast) LeaveMulticast() {
123-
// Stop sending hello
124-
if mc.helloTicker != nil {
125-
mc.helloTicker.Stop()
126-
}
127-
msg, e := makeByeMessage(mc.Payload).serialize()
138+
// Stop sending 'hello'
139+
mc.helloTicker.Stop()
140+
141+
msg, e := makeByeMessage(mc.payload).serialize()
128142
if e != nil {
129143
log.Error(e)
130144
}
@@ -158,8 +172,7 @@ func (mc *Multicast) read(b []byte) (int, *net.UDPAddr, error) {
158172
// sendHellos returns an error if failing to set up the message, otherwise it handles its own
159173
// errors (i.e. it will keep sending hellos after a failure).
160174
func (mc *Multicast) sendHellos() error {
161-
mc.helloTicker = time.NewTicker(time.Duration(mc.Period) * time.Second)
162-
msg, e := makeHelloMessage(mc.Payload).serialize()
175+
msg, e := makeHelloMessage(mc.payload).serialize()
163176
if e != nil {
164177
return e
165178
}
@@ -191,7 +204,7 @@ func (mc *Multicast) listenPeers() error {
191204
}
192205

193206
// Set a deadline to avoid blocking on a read forever
194-
e := mc.conn.SetReadDeadline(time.Now().Add(time.Duration(mc.Period) * time.Second))
207+
e := mc.conn.SetReadDeadline(time.Now().Add(time.Duration(mc.period) * time.Second))
195208
if e != nil {
196209
log.Error(e)
197210
}

src/github.com/getlantern/multicast/multicast_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ func TestMulticastMessages(t *testing.T) {
101101
t.Fatal("Unable to set socket for multicast looping")
102102
}
103103

104-
mc1.Period = 1
105-
mc1.Payload = "testHello"
104+
mc1.SetPayload("testHello")
105+
mc1.SetPeriod(1)
106106
mc1.StartMulticast()
107107
mc1.ListenPeers()
108108

@@ -144,7 +144,7 @@ func TestMulticastAnnouncing(t *testing.T) {
144144
t.Fatal("Unable to set socket for multicast looping")
145145
}
146146

147-
mc1.Period = 1
147+
mc1.SetPeriod(1)
148148
go func() {
149149
if e := mc1.sendHellos(); e != nil {
150150
log.Fatal("Error sending hellos")

0 commit comments

Comments
 (0)