Index: go/src/infra/libs/clock/testclock/testtimer.go |
diff --git a/go/src/infra/libs/clock/testclock/testtimer.go b/go/src/infra/libs/clock/testclock/testtimer.go |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8437a292b2b6e5533c2b26a849b95caefcc8dc87 |
--- /dev/null |
+++ b/go/src/infra/libs/clock/testclock/testtimer.go |
@@ -0,0 +1,77 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package testclock |
+ |
+import ( |
+ "time" |
+ |
+ "infra/libs/clock" |
+) |
+ |
+// timer is an implementation of clock.TestTimer that uses a channel |
+// to signal the timer to fire. |
+// |
+// The channel is buffered so it can be used without requiring a separate signalling |
+// goroutine. |
+type timer struct { |
+ clock *testClock // The underlying test clock instance. |
+ signalC chan time.Time // Underlying signal channel. |
+ |
+ // Cancels callback from clock.invokeAt. Being not nil implies that the timer |
+ // is active. |
+ cancelFunc cancelFunc |
+} |
+ |
+var _ clock.Timer = (*timer)(nil) |
+ |
+// NewTimer returns a new, instantiated timer. |
+func newTimer(clock *testClock) clock.Timer { |
+ t := timer{ |
+ clock: clock, |
+ } |
+ return &t |
+} |
+ |
+func (t *timer) GetC() (c <-chan time.Time) { |
+ if t.cancelFunc != nil { |
+ c = t.signalC |
+ } |
+ return |
+} |
+ |
+func (t *timer) Reset(d time.Duration) (active bool) { |
+ now := t.clock.Now() |
+ triggerTime := now.Add(d) |
+ |
+ // Signal our timerSet callback. |
+ t.clock.signalTimerSet(t) |
+ |
+ // Stop our current polling goroutine, if it's running. |
+ active = t.Stop() |
+ |
+ // Set timer properties. |
+ t.signalC = make(chan time.Time, 1) |
+ t.cancelFunc = t.clock.invokeAt(triggerTime, t.signal) |
+ return |
+} |
+ |
+func (t *timer) Stop() bool { |
+ // If the timer is not running, we're done. |
+ if t.cancelFunc == nil { |
+ return false |
+ } |
+ |
+ // Clear our state. |
+ t.cancelFunc() |
+ t.cancelFunc = nil |
+ return true |
+} |
+ |
+// Sends a single signal, clearing the channel afterwards. |
+func (t *timer) signal(now time.Time) { |
+ if t.signalC != nil { |
+ t.signalC <- now |
+ } |
+} |