Skip to content

Commit e311e2e

Browse files
authored
Merge pull request #1812 from statechannels/listeners-lock
Add concurrency control to all listeners methods
2 parents 8b177b1 + 6030044 commit e311e2e

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

node/notifier/listeners.go

+16-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type paymentChannelListeners struct {
1212
listeners []chan query.PaymentChannelInfo
1313
// prev is the previous payment channel info that was sent to the listeners.
1414
prev query.PaymentChannelInfo
15-
// listenersLock is used to protect against concurrent access to the listeners slice.
15+
// listenersLock is used to protect against concurrent access to to sibling struct members.
1616
listenersLock *sync.Mutex
1717
}
1818

@@ -24,6 +24,8 @@ func newPaymentChannelListeners() *paymentChannelListeners {
2424
// Notify notifies all listeners of a payment channel update.
2525
// It only notifies listeners if the new info is different from the previous info.
2626
func (li *paymentChannelListeners) Notify(info query.PaymentChannelInfo) {
27+
li.listenersLock.Lock()
28+
defer li.listenersLock.Unlock()
2729
if li.prev.Equal(info) {
2830
return
2931
}
@@ -45,10 +47,13 @@ func (li *paymentChannelListeners) createNewListener() <-chan query.PaymentChann
4547

4648
// getOrCreateListener returns the first listener, creating one if none exist.
4749
func (li *paymentChannelListeners) getOrCreateListener() <-chan query.PaymentChannelInfo {
50+
li.listenersLock.Lock()
4851
if len(li.listeners) != 0 {
49-
return li.listeners[0]
52+
l := li.listeners[0]
53+
li.listenersLock.Unlock()
54+
return l
5055
}
51-
56+
li.listenersLock.Unlock()
5257
return li.createNewListener()
5358
}
5459

@@ -69,7 +74,7 @@ type ledgerChannelListeners struct {
6974
listeners []chan query.LedgerChannelInfo
7075
// prev is the previous ledger channel info that was sent to the listeners.
7176
prev query.LedgerChannelInfo
72-
// listenersLock is used to protect against concurrent access to the listeners slice.
77+
// listenersLock is used to protect against concurrent access to sibling struct members.
7378
listenersLock sync.Mutex
7479
}
7580

@@ -81,6 +86,8 @@ func newLedgerChannelListeners() *ledgerChannelListeners {
8186
// Notify notifies all listeners of a ledger channel update.
8287
// It only notifies listeners if the new info is different from the previous info.
8388
func (li *ledgerChannelListeners) Notify(info query.LedgerChannelInfo) {
89+
li.listenersLock.Lock()
90+
defer li.listenersLock.Unlock()
8491
if li.prev.Equal(info) {
8592
return
8693
}
@@ -103,10 +110,13 @@ func (li *ledgerChannelListeners) createNewListener() <-chan query.LedgerChannel
103110

104111
// getOrCreateListener returns the first listener, creating one if none exist.
105112
func (li *ledgerChannelListeners) getOrCreateListener() <-chan query.LedgerChannelInfo {
113+
li.listenersLock.Lock()
106114
if len(li.listeners) != 0 {
107-
return li.listeners[0]
115+
l := li.listeners[0]
116+
li.listenersLock.Unlock()
117+
return l
108118
}
109-
119+
li.listenersLock.Unlock()
110120
return li.createNewListener()
111121
}
112122

0 commit comments

Comments
 (0)