Skip to content

Commit 9b5c715

Browse files
committed
event: use sync.Once for init for faster/cleaner locking
1 parent d52b0c3 commit 9b5c715

File tree

1 file changed

+5
-11
lines changed

1 file changed

+5
-11
lines changed

event/feed.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ var errBadChannel = errors.New("event: Subscribe argument does not have sendable
3333
//
3434
// The zero value is ready to use.
3535
type Feed struct {
36-
// sendLock has a one-element buffer and is empty when held.
37-
// It protects sendCases.
38-
sendLock chan struct{}
36+
once sync.Once // ensures that init only runs once
37+
sendLock chan struct{} // sendLock has a one-element buffer and is empty when held.It protects sendCases.
3938
removeSub chan interface{} // interrupts Send
4039
sendCases caseList // the active set of select cases used by Send
4140

@@ -60,9 +59,6 @@ func (e feedTypeError) Error() string {
6059
}
6160

6261
func (f *Feed) init() {
63-
if f.sendLock != nil {
64-
return
65-
}
6662
f.removeSub = make(chan interface{})
6763
f.sendLock = make(chan struct{}, 1)
6864
f.sendLock <- struct{}{}
@@ -75,6 +71,8 @@ func (f *Feed) init() {
7571
// The channel should have ample buffer space to avoid blocking other subscribers.
7672
// Slow subscribers are not dropped.
7773
func (f *Feed) Subscribe(channel interface{}) Subscription {
74+
f.once.Do(f.init)
75+
7876
chanval := reflect.ValueOf(channel)
7977
chantyp := chanval.Type()
8078
if chantyp.Kind() != reflect.Chan || chantyp.ChanDir()&reflect.SendDir == 0 {
@@ -84,7 +82,6 @@ func (f *Feed) Subscribe(channel interface{}) Subscription {
8482

8583
f.mu.Lock()
8684
defer f.mu.Unlock()
87-
f.init()
8885
if !f.typecheck(chantyp.Elem()) {
8986
panic(feedTypeError{op: "Subscribe", got: chantyp, want: reflect.ChanOf(reflect.SendDir, f.etype)})
9087
}
@@ -130,10 +127,7 @@ func (f *Feed) remove(sub *feedSub) {
130127
// Send delivers to all subscribed channels simultaneously.
131128
// It returns the number of subscribers that the value was sent to.
132129
func (f *Feed) Send(value interface{}) (nsent int) {
133-
f.mu.Lock()
134-
f.init()
135-
f.mu.Unlock()
136-
130+
f.once.Do(f.init)
137131
<-f.sendLock
138132

139133
// Add new cases from the inbox after taking the send lock.

0 commit comments

Comments
 (0)