19
19
20
20
// PeerQueue provides a queer of messages to be sent for a single peer.
21
21
type PeerQueue interface {
22
- RefIncrement ()
23
- RefDecrement () bool
24
- RefCount () int
25
22
AddMessage (entries []* bsmsg.Entry , ses uint64 )
26
23
Startup (ctx context.Context )
27
24
AddWantlist (initialEntries []* wantlist.Entry )
@@ -35,10 +32,15 @@ type peerMessage interface {
35
32
handle (pm * PeerManager )
36
33
}
37
34
35
+ type peerQueueInstance struct {
36
+ refcnt int
37
+ pq PeerQueue
38
+ }
39
+
38
40
// PeerManager manages a pool of peers and sends messages to peers in the pool.
39
41
type PeerManager struct {
40
42
// peerQueues -- interact through internal utility functions get/set/remove/iterate
41
- peerQueues map [peer.ID ]PeerQueue
43
+ peerQueues map [peer.ID ]* peerQueueInstance
42
44
peerQueuesLk sync.RWMutex
43
45
44
46
createPeerQueue PeerQueueFactory
@@ -48,7 +50,7 @@ type PeerManager struct {
48
50
// New creates a new PeerManager, given a context and a peerQueueFactory.
49
51
func New (ctx context.Context , createPeerQueue PeerQueueFactory ) * PeerManager {
50
52
return & PeerManager {
51
- peerQueues : make (map [peer.ID ]PeerQueue ),
53
+ peerQueues : make (map [peer.ID ]* peerQueueInstance ),
52
54
createPeerQueue : createPeerQueue ,
53
55
ctx : ctx ,
54
56
}
@@ -68,28 +70,39 @@ func (pm *PeerManager) ConnectedPeers() []peer.ID {
68
70
// Connected is called to add a new peer to the pool, and send it an initial set
69
71
// of wants.
70
72
func (pm * PeerManager ) Connected (p peer.ID , initialEntries []* wantlist.Entry ) {
71
- mq := pm .getOrCreate (p )
73
+ pm .peerQueuesLk .Lock ()
74
+
75
+ pq := pm .getOrCreate (p )
72
76
73
- if mq . RefCount () == 0 {
74
- mq .AddWantlist (initialEntries )
77
+ if pq . refcnt == 0 {
78
+ pq . pq .AddWantlist (initialEntries )
75
79
}
76
- mq .RefIncrement ()
80
+
81
+ pq .refcnt ++
82
+
83
+ pm .peerQueuesLk .Unlock ()
77
84
}
78
85
79
86
// Disconnected is called to remove a peer from the pool.
80
87
func (pm * PeerManager ) Disconnected (p peer.ID ) {
81
88
pm .peerQueuesLk .Lock ()
82
89
pq , ok := pm .peerQueues [p ]
83
90
84
- if ! ok || pq .RefDecrement () {
91
+ if ! ok {
92
+ pm .peerQueuesLk .Unlock ()
93
+ return
94
+ }
95
+
96
+ pq .refcnt --
97
+ if pq .refcnt > 0 {
85
98
pm .peerQueuesLk .Unlock ()
86
99
return
87
100
}
88
101
89
102
delete (pm .peerQueues , p )
90
103
pm .peerQueuesLk .Unlock ()
91
104
92
- pq .Shutdown ()
105
+ pq .pq . Shutdown ()
93
106
94
107
}
95
108
@@ -99,25 +112,26 @@ func (pm *PeerManager) SendMessage(entries []*bsmsg.Entry, targets []peer.ID, fr
99
112
if len (targets ) == 0 {
100
113
pm .peerQueuesLk .RLock ()
101
114
for _ , p := range pm .peerQueues {
102
- p .AddMessage (entries , from )
115
+ p .pq . AddMessage (entries , from )
103
116
}
104
117
pm .peerQueuesLk .RUnlock ()
105
118
} else {
106
119
for _ , t := range targets {
107
- p := pm .getOrCreate (t )
108
- p .AddMessage (entries , from )
120
+ pm .peerQueuesLk .Lock ()
121
+ pqi := pm .getOrCreate (t )
122
+ pm .peerQueuesLk .Unlock ()
123
+ pqi .pq .AddMessage (entries , from )
109
124
}
110
125
}
111
126
}
112
127
113
- func (pm * PeerManager ) getOrCreate (p peer.ID ) PeerQueue {
114
- pm .peerQueuesLk .Lock ()
115
- pq , ok := pm .peerQueues [p ]
128
+ func (pm * PeerManager ) getOrCreate (p peer.ID ) * peerQueueInstance {
129
+ pqi , ok := pm .peerQueues [p ]
116
130
if ! ok {
117
- pq = pm .createPeerQueue (p )
131
+ pq : = pm .createPeerQueue (p )
118
132
pq .Startup (pm .ctx )
119
- pm .peerQueues [p ] = pq
133
+ pqi = & peerQueueInstance {0 , pq }
134
+ pm .peerQueues [p ] = pqi
120
135
}
121
- pm .peerQueuesLk .Unlock ()
122
- return pq
136
+ return pqi
123
137
}
0 commit comments