Skip to content
This repository was archived by the owner on Jan 16, 2025. It is now read-only.

Commit 2e88c1c

Browse files
dbadoyfjl
authored andcommitted
event: move type fixation logic into Feed.init (ethereum#27249)
This is a minor optimization/refactoring of Feed. --------- Co-authored-by: Felix Lange <[email protected]>
1 parent 71cca83 commit 2e88c1c

File tree

1 file changed

+12
-22
lines changed

1 file changed

+12
-22
lines changed

event/feed.go

+12-22
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ func (e feedTypeError) Error() string {
5757
return "event: wrong type in " + e.op + " got " + e.got.String() + ", want " + e.want.String()
5858
}
5959

60-
func (f *Feed) init() {
60+
func (f *Feed) init(etype reflect.Type) {
61+
f.etype = etype
6162
f.removeSub = make(chan interface{})
6263
f.sendLock = make(chan struct{}, 1)
6364
f.sendLock <- struct{}{}
@@ -70,36 +71,27 @@ func (f *Feed) init() {
7071
// The channel should have ample buffer space to avoid blocking other subscribers.
7172
// Slow subscribers are not dropped.
7273
func (f *Feed) Subscribe(channel interface{}) Subscription {
73-
f.once.Do(f.init)
74-
7574
chanval := reflect.ValueOf(channel)
7675
chantyp := chanval.Type()
7776
if chantyp.Kind() != reflect.Chan || chantyp.ChanDir()&reflect.SendDir == 0 {
7877
panic(errBadChannel)
7978
}
8079
sub := &feedSub{feed: f, channel: chanval, err: make(chan error, 1)}
8180

82-
f.mu.Lock()
83-
defer f.mu.Unlock()
84-
if !f.typecheck(chantyp.Elem()) {
81+
f.once.Do(func() { f.init(chantyp.Elem()) })
82+
if f.etype != chantyp.Elem() {
8583
panic(feedTypeError{op: "Subscribe", got: chantyp, want: reflect.ChanOf(reflect.SendDir, f.etype)})
8684
}
85+
86+
f.mu.Lock()
87+
defer f.mu.Unlock()
8788
// Add the select case to the inbox.
8889
// The next Send will add it to f.sendCases.
8990
cas := reflect.SelectCase{Dir: reflect.SelectSend, Chan: chanval}
9091
f.inbox = append(f.inbox, cas)
9192
return sub
9293
}
9394

94-
// note: callers must hold f.mu
95-
func (f *Feed) typecheck(typ reflect.Type) bool {
96-
if f.etype == nil {
97-
f.etype = typ
98-
return true
99-
}
100-
return f.etype == typ
101-
}
102-
10395
func (f *Feed) remove(sub *feedSub) {
10496
// Delete from inbox first, which covers channels
10597
// that have not been added to f.sendCases yet.
@@ -128,19 +120,17 @@ func (f *Feed) remove(sub *feedSub) {
128120
func (f *Feed) Send(value interface{}) (nsent int) {
129121
rvalue := reflect.ValueOf(value)
130122

131-
f.once.Do(f.init)
123+
f.once.Do(func() { f.init(rvalue.Type()) })
124+
if f.etype != rvalue.Type() {
125+
panic(feedTypeError{op: "Send", got: rvalue.Type(), want: f.etype})
126+
}
127+
132128
<-f.sendLock
133129

134130
// Add new cases from the inbox after taking the send lock.
135131
f.mu.Lock()
136132
f.sendCases = append(f.sendCases, f.inbox...)
137133
f.inbox = nil
138-
139-
if !f.typecheck(rvalue.Type()) {
140-
f.sendLock <- struct{}{}
141-
f.mu.Unlock()
142-
panic(feedTypeError{op: "Send", got: rvalue.Type(), want: f.etype})
143-
}
144134
f.mu.Unlock()
145135

146136
// Set the sent value on all channels.

0 commit comments

Comments
 (0)