p2p: make registries thread safer
License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
Łukasz Magiera committed
May 25, 2018 at 16:12 UTC
058edaff589de9f4bf23e05956ae2714088e0d3b
4 files changed
+35
-12
p2p/listener.go
+15
-4
@@ -1,5 +1,9 @@
1
package p2p
2
3
+import (
4
+ "sync"
5
+)
6
+
7
type Listener interface {
8
Protocol() string
9
ListenAddress() string
@@ -18,16 +22,23 @@ type listenerKey struct {
22
// ListenerRegistry is a collection of local application proto listeners.
23
type ListenerRegistry struct {
24
Listeners map[listenerKey]Listener
25
+ lk *sync.Mutex
26
}
27
28
// Register registers listenerInfo in this registry
24
-func (c *ListenerRegistry) Register(l Listener) {
25
- c.Listeners[getListenerKey(l)] = l
29
+func (r *ListenerRegistry) Register(l Listener) {
30
+ r.lk.Lock()
31
+ defer r.lk.Unlock()
32
+
33
+ r.Listeners[getListenerKey(l)] = l
34
}
35
36
// Deregister removes p2p listener from this registry
29
-func (c *ListenerRegistry) Deregister(k listenerKey) {
30
- delete(c.Listeners, k)
37
+func (r *ListenerRegistry) Deregister(k listenerKey) {
38
+ r.lk.Lock()
39
+ defer r.lk.Unlock()
40
+
41
+ delete(r.Listeners, k)
42
}
43
44
func getListenerKey(l Listener) listenerKey {
p2p/p2p.go
+4
@@ -1,6 +1,8 @@
1
package p2p
2
3
import (
4
+ "sync"
5
+
6
pstore "gx/ipfs/QmZR2XWVVBCtbgBWnQhWk2xcQfaR3W8faQPriAiaaj7rsr/go-libp2p-peerstore"
7
p2phost "gx/ipfs/Qmb8T6YBBsjYsVGfrihQLfCJveczZnneSBqBKkYEBWDjge/go-libp2p-host"
8
peer "gx/ipfs/QmdVrMn1LhB4ybb8hMVaMLXnA8XRSewMnK6YqXKXoTcRvN/go-libp2p-peer"
@@ -25,9 +27,11 @@ func NewP2P(identity peer.ID, peerHost p2phost.Host, peerstore pstore.Peerstore)
27
28
Listeners: &ListenerRegistry{
29
Listeners: map[listenerKey]Listener{},
30
+ lk: &sync.Mutex{},
31
},
32
Streams: &StreamRegistry{
33
Streams: map[uint64]*Stream{},
34
+ lk: &sync.Mutex{},
35
},
36
}
37
}
p2p/remote.go
+2
-2
@@ -38,7 +38,7 @@ func (p2p *P2P) ForwardRemote(ctx context.Context, proto string, addr ma.Multiad
38
return
39
}
40
41
- stream := Stream{
41
+ stream := &Stream{
42
Protocol: proto,
43
44
OriginAddr: remote.Conn().RemoteMultiaddr(),
@@ -50,7 +50,7 @@ func (p2p *P2P) ForwardRemote(ctx context.Context, proto string, addr ma.Multiad
50
Registry: p2p.Streams,
51
}
52
53
- p2p.Streams.Register(&stream)
53
+ p2p.Streams.Register(stream)
54
stream.startStreaming()
55
})
56
p2p/stream.go
+14
-6
@@ -2,6 +2,7 @@ package p2p
2
3
import (
4
"io"
5
+ "sync"
6
7
ma "gx/ipfs/QmWWQ2Txc2c6tqjsBpzg5Ar652cHPGNsQQp2SejkNmkUMb/go-multiaddr"
8
net "gx/ipfs/QmYj8wdn5sZEHX2XMDWGBvcXJNdzVbaVpHmXvhHBVZepen/go-libp2p-net"
@@ -58,18 +59,25 @@ func (s *Stream) startStreaming() {
59
// StreamRegistry is a collection of active incoming and outgoing proto app streams.
60
type StreamRegistry struct {
61
Streams map[uint64]*Stream
62
+ lk *sync.Mutex
63
64
nextId uint64
65
}
66
67
// Register registers a stream to the registry
66
-func (c *StreamRegistry) Register(streamInfo *Stream) {
67
- streamInfo.Id = c.nextId
68
- c.Streams[c.nextId] = streamInfo
69
- c.nextId++
68
+func (r *StreamRegistry) Register(streamInfo *Stream) {
69
+ r.lk.Lock()
70
+ defer r.lk.Unlock()
71
+
72
+ streamInfo.Id = r.nextId
73
+ r.Streams[r.nextId] = streamInfo
74
+ r.nextId++
75
}
76
77
// Deregister deregisters stream from the registry
73
-func (c *StreamRegistry) Deregister(streamId uint64) {
74
- delete(c.Streams, streamId)
78
+func (r *StreamRegistry) Deregister(streamId uint64) {
79
+ r.lk.Lock()
80
+ defer r.lk.Unlock()
81
+
82
+ delete(r.Streams, streamId)
83
}