@cryptotaxi247 / kubo / commits / 058edaff5

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 }