diff options
Diffstat (limited to 'libgo/go/time/sleep.go')
-rw-r--r-- | libgo/go/time/sleep.go | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/libgo/go/time/sleep.go b/libgo/go/time/sleep.go index 73114f5eecd..4b01404896e 100644 --- a/libgo/go/time/sleep.go +++ b/libgo/go/time/sleep.go @@ -12,7 +12,7 @@ func Sleep(d Duration) func runtimeNano() int64 // Interface to timers implemented in package runtime. -// Must be in sync with ../runtime/runtime.h:/^struct.Timer$ +// Must be in sync with ../runtime/time.go:/^type timer type runtimeTimer struct { i int when int64 @@ -55,13 +55,22 @@ type Timer struct { // Stop does not close the channel, to prevent a read from the channel succeeding // incorrectly. // -// To prevent the timer firing after a call to Stop, -// check the return value and drain the channel. For example: +// To prevent a timer created with NewTimer from firing after a call to Stop, +// check the return value and drain the channel. +// For example, assuming the program has not received from t.C already: +// // if !t.Stop() { // <-t.C // } +// // This cannot be done concurrent to other receives from the Timer's // channel. +// +// For a timer created with AfterFunc(d, f), if t.Stop returns false, then the timer +// has already expired and the function f has been started in its own goroutine; +// Stop does not wait for f to complete before returning. +// If the caller needs to know whether f is completed, it must coordinate +// with f explicitly. func (t *Timer) Stop() bool { if t.r.f == nil { panic("time: Stop called on uninitialized Timer") @@ -89,18 +98,25 @@ func NewTimer(d Duration) *Timer { // It returns true if the timer had been active, false if the timer had // expired or been stopped. // -// To reuse an active timer, always call its Stop method first and—if it had -// expired—drain the value from its channel. For example: +// Resetting a timer must take care not to race with the send into t.C +// that happens when the current timer expires. +// If a program has already received a value from t.C, the timer is known +// to have expired, and t.Reset can be used directly. +// If a program has not yet received a value from t.C, however, +// the timer must be stopped and—if Stop reports that the timer expired +// before being stopped—the channel explicitly drained: +// // if !t.Stop() { // <-t.C // } // t.Reset(d) +// // This should not be done concurrent to other receives from the Timer's // channel. // // Note that it is not possible to use Reset's return value correctly, as there // is a race condition between draining the channel and the new timer expiring. -// Reset should always be used in concert with Stop, as described above. +// Reset should always be invoked on stopped or expired channels, as described above. // The return value exists to preserve compatibility with existing programs. func (t *Timer) Reset(d Duration) bool { if t.r.f == nil { |