expand ticker interface to allow a client to shut down a ticker.
existing interface still works.
R=rsc
DELTA=50 (32 added, 2 deleted, 16 changed)
OCL=34930
CL=34932
diff --git a/src/pkg/time/tick.go b/src/pkg/time/tick.go
index e716ba5..b664077 100644
--- a/src/pkg/time/tick.go
+++ b/src/pkg/time/tick.go
@@ -7,7 +7,7 @@
// TODO(rsc): This implementation of Tick is a
// simple placeholder. Eventually, there will need to be
// a single central time server no matter how many tickers
-// are active. There also needs to be a way to cancel a ticker.
+// are active.
//
// Also, if timeouts become part of the select statement,
// perhaps the Ticker is just:
@@ -19,40 +19,63 @@
// c <- nsec;
// }
-func ticker(ns int64, c chan int64) {
+
+// A Ticker holds a synchronous channel that delivers `ticks' of a clock
+// at intervals.
+type Ticker struct {
+ C <-chan int64; // The channel on which the ticks are delivered.
+ ns int64;
+ shutdown bool;
+}
+
+// Stop turns off a ticker. After Stop, no more ticks will be delivered.
+func (t *Ticker) Stop() {
+ t.shutdown = true
+}
+
+func (t *Ticker) ticker(c chan<- int64) {
now := Nanoseconds();
when := now;
- for {
- when += ns; // next alarm
+ for !t.shutdown {
+ when += t.ns; // next alarm
// if c <- now took too long, skip ahead
if when < now {
// one big step
- when += (now-when)/ns * ns;
+ when += (now-when)/t.ns * t.ns;
}
for when <= now {
// little steps until when > now
- when += ns
+ when += t.ns
}
Sleep(when - now);
now = Nanoseconds();
- c <- now;
- if closed(c) {
+ if t.shutdown {
return;
}
+ c <- now;
}
}
-// Tick creates a synchronous channel that will send the time, in nanoseconds,
-// every ns nanoseconds. It adjusts the intervals to make up for pauses in
-// delivery of the ticks.
-func Tick(ns int64) chan int64 {
+// Tick is a convenience wrapper for NewTicker providing access to the ticking
+// channel only. Useful for clients that have no need to shut down the ticker.
+func Tick(ns int64) <-chan int64 {
+ if ns <= 0 {
+ return nil
+ }
+ return NewTicker(ns).C;
+}
+
+// Ticker returns a new Ticker containing a synchronous channel that will
+// send the time, in nanoseconds, every ns nanoseconds. It adjusts the
+// intervals to make up for pauses in delivery of the ticks.
+func NewTicker(ns int64) *Ticker {
if ns <= 0 {
return nil
}
c := make(chan int64);
- go ticker(ns, c);
- return c;
+ t := &Ticker{c, ns, false};
+ go t.ticker(c);
+ return t;
}
-