From d6e34761dc129f1e471bf475fd2008c1a2dfac1a 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 e83b9150f..e26b830d5 100644 --- a/lib/events/events.go +++ b/lib/events/events.go @@ -188,12 +188,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 26fd888c1..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" ) -const timeout = 500 * 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() {