From feffc0416fc7a6267b1da7fab10164742fbc60c9 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Mon, 24 Aug 2015 09:38:39 +0200 Subject: [PATCH] Fix events timeout errors Resetting the timeout doesn't fully cut it, as it may timeout after we got an event and be delivered later. This should fix it well enough for the moment. https://github.com/golang/go/issues/11513 --- lib/events/events.go | 9 ++++++++- lib/events/events_test.go | 12 ++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/events/events.go b/lib/events/events.go index 78c1d692f..9f7c53522 100644 --- a/lib/events/events.go +++ b/lib/events/events.go @@ -182,12 +182,19 @@ func (s *Subscription) Poll(timeout time.Duration) (Event, error) { dl.Debugln("poll", timeout) } - s.timeout.Reset(timeout) + if !s.timeout.Reset(timeout) { + select { + case <-s.timeout.C: + default: + } + } + select { case e, ok := <-s.events: if !ok { return e, ErrClosed } + s.timeout.Stop() return e, nil case <-s.timeout.C: return Event{}, ErrTimeout diff --git a/lib/events/events_test.go b/lib/events/events_test.go index 982953d94..2f91dafea 100644 --- a/lib/events/events_test.go +++ b/lib/events/events_test.go @@ -14,7 +14,7 @@ import ( "github.com/syncthing/syncthing/lib/events" ) -var timeout = 100 * time.Millisecond +const timeout = 100 * time.Millisecond func TestNewLogger(t *testing.T) { l := events.NewLogger() @@ -26,6 +26,7 @@ func TestNewLogger(t *testing.T) { func TestSubscriber(t *testing.T) { l := events.NewLogger() s := l.Subscribe(0) + defer l.Unsubscribe(s) if s == nil { t.Fatal("Unexpected nil Subscription") } @@ -34,6 +35,7 @@ func TestSubscriber(t *testing.T) { func TestTimeout(t *testing.T) { l := events.NewLogger() s := l.Subscribe(0) + defer l.Unsubscribe(s) _, err := s.Poll(timeout) if err != events.ErrTimeout { t.Fatal("Unexpected non-Timeout error:", err) @@ -45,6 +47,7 @@ func TestEventBeforeSubscribe(t *testing.T) { l.Log(events.DeviceConnected, "foo") s := l.Subscribe(0) + defer l.Unsubscribe(s) _, err := s.Poll(timeout) if err != events.ErrTimeout { @@ -56,6 +59,7 @@ func TestEventAfterSubscribe(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.AllEvents) + defer l.Unsubscribe(s) l.Log(events.DeviceConnected, "foo") ev, err := s.Poll(timeout) @@ -80,6 +84,7 @@ func TestEventAfterSubscribeIgnoreMask(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.DeviceDisconnected) + defer l.Unsubscribe(s) l.Log(events.DeviceConnected, "foo") _, err := s.Poll(timeout) @@ -91,7 +96,8 @@ func TestEventAfterSubscribeIgnoreMask(t *testing.T) { func TestBufferOverflow(t *testing.T) { l := events.NewLogger() - _ = l.Subscribe(events.AllEvents) + s := l.Subscribe(events.AllEvents) + defer l.Unsubscribe(s) t0 := time.Now() for i := 0; i < events.BufferSize*2; i++ { @@ -126,6 +132,7 @@ func TestIDs(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.AllEvents) + defer l.Unsubscribe(s) l.Log(events.DeviceConnected, "foo") l.Log(events.DeviceConnected, "bar") @@ -154,6 +161,7 @@ func TestBufferedSub(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.AllEvents) + defer l.Unsubscribe(s) bs := events.NewBufferedSubscription(s, 10*events.BufferSize) go func() {