github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/time/sleep.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package time 6 7 // Sleep pauses the current goroutine for the duration d. 8 func Sleep(d Duration) 9 10 func nano() int64 { 11 sec, nsec := now() 12 return sec*1e9 + int64(nsec) 13 } 14 15 // Interface to timers implemented in package runtime. 16 // Must be in sync with ../runtime/runtime.h:/^struct.Timer$ 17 type runtimeTimer struct { 18 i int32 19 when int64 20 period int64 21 f func(int64, interface{}) // NOTE: must not be closure 22 arg interface{} 23 } 24 25 // when is a helper function for setting the 'when' field of a runtimeTimer. 26 // It returns what the time will be, in nanoseconds, Duration d in the future. 27 // If d is negative, it is ignored. If the returned value would be less than 28 // zero because of an overflow, MaxInt64 is returned. 29 func when(d Duration) int64 { 30 if d <= 0 { 31 return nano() 32 } 33 t := nano() + int64(d) 34 if t < 0 { 35 t = 1<<63 - 1 // math.MaxInt64 36 } 37 return t 38 } 39 40 func startTimer(*runtimeTimer) 41 func stopTimer(*runtimeTimer) bool 42 43 // The Timer type represents a single event. 44 // When the Timer expires, the current time will be sent on C, 45 // unless the Timer was created by AfterFunc. 46 type Timer struct { 47 C <-chan Time 48 r runtimeTimer 49 } 50 51 // Stop prevents the Timer from firing. 52 // It returns true if the call stops the timer, false if the timer has already 53 // expired or been stopped. 54 // Stop does not close the channel, to prevent a read from the channel succeeding 55 // incorrectly. 56 func (t *Timer) Stop() bool { 57 return stopTimer(&t.r) 58 } 59 60 // NewTimer creates a new Timer that will send 61 // the current time on its channel after at least duration d. 62 func NewTimer(d Duration) *Timer { 63 c := make(chan Time, 1) 64 t := &Timer{ 65 C: c, 66 r: runtimeTimer{ 67 when: when(d), 68 f: sendTime, 69 arg: c, 70 }, 71 } 72 startTimer(&t.r) 73 return t 74 } 75 76 // Reset changes the timer to expire after duration d. 77 // It returns true if the timer had been active, false if the timer had 78 // expired or been stopped. 79 func (t *Timer) Reset(d Duration) bool { 80 w := when(d) 81 active := stopTimer(&t.r) 82 t.r.when = w 83 startTimer(&t.r) 84 return active 85 } 86 87 func sendTime(now int64, c interface{}) { 88 // Non-blocking send of time on c. 89 // Used in NewTimer, it cannot block anyway (buffer). 90 // Used in NewTicker, dropping sends on the floor is 91 // the desired behavior when the reader gets behind, 92 // because the sends are periodic. 93 select { 94 case c.(chan Time) <- Unix(0, now): 95 default: 96 } 97 } 98 99 // After waits for the duration to elapse and then sends the current time 100 // on the returned channel. 101 // It is equivalent to NewTimer(d).C. 102 func After(d Duration) <-chan Time { 103 return NewTimer(d).C 104 } 105 106 // AfterFunc waits for the duration to elapse and then calls f 107 // in its own goroutine. It returns a Timer that can 108 // be used to cancel the call using its Stop method. 109 func AfterFunc(d Duration, f func()) *Timer { 110 t := &Timer{ 111 r: runtimeTimer{ 112 when: when(d), 113 f: goFunc, 114 arg: f, 115 }, 116 } 117 startTimer(&t.r) 118 return t 119 } 120 121 func goFunc(now int64, arg interface{}) { 122 go arg.(func())() 123 }