fix a few race conditions in mocknet
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Oct 19, 2015 at 17:20 UTC
def46978525d47b2c75a1f969102a034547cfc21
2 files changed
+34
-28
p2p/net/mock/mock_net.go
+28
-28
@@ -34,7 +34,7 @@ type mocknet struct {
34
35
proc goprocess.Process // for Context closing
36
ctx context.Context
37
- sync.RWMutex
37
+ sync.Mutex
38
}
39
40
func New(ctx context.Context) Mocknet {
@@ -95,8 +95,8 @@ func (mn *mocknet) AddPeerWithPeerstore(p peer.ID, ps peer.Peerstore) (host.Host
95
}
96
97
func (mn *mocknet) Peers() []peer.ID {
98
- mn.RLock()
99
- defer mn.RUnlock()
98
+ mn.Lock()
99
+ defer mn.Unlock()
100
101
cp := make([]peer.ID, 0, len(mn.nets))
102
for _, n := range mn.nets {
@@ -107,22 +107,22 @@ func (mn *mocknet) Peers() []peer.ID {
107
}
108
109
func (mn *mocknet) Host(pid peer.ID) host.Host {
110
- mn.RLock()
110
+ mn.Lock()
111
host := mn.hosts[pid]
112
- mn.RUnlock()
112
+ mn.Unlock()
113
return host
114
}
115
116
func (mn *mocknet) Net(pid peer.ID) inet.Network {
117
- mn.RLock()
117
+ mn.Lock()
118
n := mn.nets[pid]
119
- mn.RUnlock()
119
+ mn.Unlock()
120
return n
121
}
122
123
func (mn *mocknet) Hosts() []host.Host {
124
- mn.RLock()
125
- defer mn.RUnlock()
124
+ mn.Lock()
125
+ defer mn.Unlock()
126
127
cp := make([]host.Host, 0, len(mn.hosts))
128
for _, h := range mn.hosts {
@@ -134,8 +134,8 @@ func (mn *mocknet) Hosts() []host.Host {
134
}
135
136
func (mn *mocknet) Nets() []inet.Network {
137
- mn.RLock()
138
- defer mn.RUnlock()
137
+ mn.Lock()
138
+ defer mn.Unlock()
139
140
cp := make([]inet.Network, 0, len(mn.nets))
141
for _, n := range mn.nets {
@@ -148,8 +148,8 @@ func (mn *mocknet) Nets() []inet.Network {
148
// Links returns a copy of the internal link state map.
149
// (wow, much map. so data structure. how compose. ahhh pointer)
150
func (mn *mocknet) Links() LinkMap {
151
- mn.RLock()
152
- defer mn.RUnlock()
151
+ mn.Lock()
152
+ defer mn.Unlock()
153
154
links := map[string]map[string]map[Link]struct{}{}
155
for p1, lm := range mn.links {
@@ -179,10 +179,10 @@ func (mn *mocknet) LinkAll() error {
179
}
180
181
func (mn *mocknet) LinkPeers(p1, p2 peer.ID) (Link, error) {
182
- mn.RLock()
182
+ mn.Lock()
183
n1 := mn.nets[p1]
184
n2 := mn.nets[p2]
185
- mn.RUnlock()
185
+ mn.Unlock()
186
187
if n1 == nil {
188
return nil, fmt.Errorf("network for p1 not in mocknet")
@@ -211,11 +211,11 @@ func (mn *mocknet) validate(n inet.Network) (*peernet, error) {
211
}
212
213
func (mn *mocknet) LinkNets(n1, n2 inet.Network) (Link, error) {
214
- mn.RLock()
214
+ mn.Lock()
215
n1r, err1 := mn.validate(n1)
216
n2r, err2 := mn.validate(n2)
217
ld := mn.linkDefaults
218
- mn.RUnlock()
218
+ mn.Unlock()
219
220
if err1 != nil {
221
return nil, err1
@@ -260,7 +260,7 @@ func (mn *mocknet) UnlinkNets(n1, n2 inet.Network) error {
260
}
261
262
// get from the links map. and lazily contruct.
263
-func (mn *mocknet) linksMapGet(p1, p2 peer.ID) *map[*link]struct{} {
263
+func (mn *mocknet) linksMapGet(p1, p2 peer.ID) map[*link]struct{} {
264
265
l1, found := mn.links[p1]
266
if !found {
@@ -275,7 +275,7 @@ func (mn *mocknet) linksMapGet(p1, p2 peer.ID) *map[*link]struct{} {
275
l2 = l1[p2]
276
}
277
278
- return &l2
278
+ return l2
279
}
280
281
func (mn *mocknet) addLink(l *link) {
@@ -283,8 +283,8 @@ func (mn *mocknet) addLink(l *link) {
283
defer mn.Unlock()
284
285
n1, n2 := l.nets[0], l.nets[1]
286
- (*mn.linksMapGet(n1.peer, n2.peer))[l] = struct{}{}
287
- (*mn.linksMapGet(n2.peer, n1.peer))[l] = struct{}{}
286
+ mn.linksMapGet(n1.peer, n2.peer)[l] = struct{}{}
287
+ mn.linksMapGet(n2.peer, n1.peer)[l] = struct{}{}
288
}
289
290
func (mn *mocknet) removeLink(l *link) {
@@ -292,8 +292,8 @@ func (mn *mocknet) removeLink(l *link) {
292
defer mn.Unlock()
293
294
n1, n2 := l.nets[0], l.nets[1]
295
- delete(*mn.linksMapGet(n1.peer, n2.peer), l)
296
- delete(*mn.linksMapGet(n2.peer, n1.peer), l)
295
+ delete(mn.linksMapGet(n1.peer, n2.peer), l)
296
+ delete(mn.linksMapGet(n2.peer, n1.peer), l)
297
}
298
299
func (mn *mocknet) ConnectAllButSelf() error {
@@ -329,10 +329,10 @@ func (mn *mocknet) DisconnectNets(n1, n2 inet.Network) error {
329
}
330
331
func (mn *mocknet) LinksBetweenPeers(p1, p2 peer.ID) []Link {
332
- mn.RLock()
333
- defer mn.RUnlock()
332
+ mn.Lock()
333
+ defer mn.Unlock()
334
335
- ls2 := *mn.linksMapGet(p1, p2)
335
+ ls2 := mn.linksMapGet(p1, p2)
336
cp := make([]Link, 0, len(ls2))
337
for l := range ls2 {
338
cp = append(cp, l)
@@ -351,8 +351,8 @@ func (mn *mocknet) SetLinkDefaults(o LinkOptions) {
351
}
352
353
func (mn *mocknet) LinkDefaults() LinkOptions {
354
- mn.RLock()
355
- defer mn.RUnlock()
354
+ mn.Lock()
355
+ defer mn.Unlock()
356
return mn.linkDefaults
357
}
358
p2p/net/mock/ratelimiter.go
+6
@@ -1,12 +1,14 @@
1
package mocknet
2
3
import (
4
+ "sync"
5
"time"
6
)
7
8
// A ratelimiter is used by a link to determine how long to wait before sending
9
// data given a bandwidth cap.
10
type ratelimiter struct {
11
+ lock sync.Mutex
12
bandwidth float64 // bytes per nanosecond
13
allowance float64 // in bytes
14
maxAllowance float64 // in bytes
@@ -29,6 +31,8 @@ func NewRatelimiter(bandwidth float64) *ratelimiter {
31
32
// Changes bandwidth of a ratelimiter and resets its allowance
33
func (r *ratelimiter) UpdateBandwidth(bandwidth float64) {
34
+ r.lock.Lock()
35
+ defer r.lock.Unlock()
36
// Convert bandwidth from bytes/second to bytes/nanosecond
37
b := bandwidth / float64(time.Second)
38
r.bandwidth = b
@@ -40,6 +44,8 @@ func (r *ratelimiter) UpdateBandwidth(bandwidth float64) {
44
45
// Returns how long to wait before sending data with length 'dataSize' bytes
46
func (r *ratelimiter) Limit(dataSize int) time.Duration {
47
+ r.lock.Lock()
48
+ defer r.lock.Unlock()
49
// update time
50
var duration time.Duration = time.Duration(0)
51
if r.bandwidth == 0 {