From 65738c1eb37c789294124cc9b4bbe6d55d50a77f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 20 Oct 2017 14:01:38 +0300 Subject: [PATCH] event: fix datarace between Subscribe and Send --- event/feed.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/event/feed.go b/event/feed.go index b1b597f17b..78fa3d98d8 100644 --- a/event/feed.go +++ b/event/feed.go @@ -127,6 +127,8 @@ func (f *Feed) remove(sub *feedSub) { // Send delivers to all subscribed channels simultaneously. // It returns the number of subscribers that the value was sent to. func (f *Feed) Send(value interface{}) (nsent int) { + rvalue := reflect.ValueOf(value) + f.once.Do(f.init) <-f.sendLock @@ -134,14 +136,14 @@ func (f *Feed) Send(value interface{}) (nsent int) { f.mu.Lock() f.sendCases = append(f.sendCases, f.inbox...) f.inbox = nil - f.mu.Unlock() - // Set the sent value on all channels. - rvalue := reflect.ValueOf(value) if !f.typecheck(rvalue.Type()) { f.sendLock <- struct{}{} panic(feedTypeError{op: "Send", got: rvalue.Type(), want: f.etype}) } + f.mu.Unlock() + + // Set the sent value on all channels. for i := firstSubSendCase; i < len(f.sendCases); i++ { f.sendCases[i].Send = rvalue }