@cryptotaxi247 / kubo / commits / def469785

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 {