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.
14 // The event type represents a single After or AfterFunc event.
16 t int64 // The absolute time that the event should fire.
17 f func(int64) // The function to call when the event fires.
18 sleeping bool // A sleeper is sleeping for this event.
21 type eventHeap []*event
24 var eventMutex sync.Mutex
27 events.Push(&event{1 << 62, nil, true}) // sentinel
30 // Sleep pauses the current goroutine for at least ns nanoseconds.
31 // Higher resolution sleeping may be provided by syscall.Nanosleep
32 // on some operating systems.
33 func Sleep(ns int64) os.Error {
34 _, err := sleep(Nanoseconds(), ns)
38 // sleep takes the current time and a duration,
39 // pauses for at least ns nanoseconds, and
40 // returns the current time and an error.
41 func sleep(t, ns int64) (int64, os.Error) {
42 // TODO(cw): use monotonic-time once it's available
45 errno := syscall.Sleep(end - t)
46 if errno != 0 && errno != syscall.EINTR {
47 return 0, os.NewSyscallError("sleep", errno)
54 // After waits at least ns nanoseconds before sending the current time
55 // on the returned channel.
56 func After(ns int64) <-chan int64 {
57 c := make(chan int64, 1)
58 after(ns, func(t int64) { c <- t })
62 // AfterFunc waits at least ns nanoseconds before calling f
63 // in its own goroutine.
64 func AfterFunc(ns int64, f func()) {
65 after(ns, func(_ int64) {
70 // after is the implementation of After and AfterFunc.
71 // When the current time is after ns, it calls f with the current time.
72 // It assumes that f will not block.
73 func after(ns int64, f func(int64)) {
74 t := Nanoseconds() + ns
77 heap.Push(events, &event{t, f, false})
84 // sleeper continually looks at the earliest event in the queue, marks it
85 // as sleeping, waits until it happens, then removes any events
86 // in the queue that are due. It stops when it finds an event that is
87 // already marked as sleeping. When an event is inserted before the first item,
88 // a new sleeper is started.
90 // Scheduling vagaries mean that sleepers may not wake up in
91 // exactly the order of the events that they are waiting for,
92 // but this does not matter as long as there are at least as
93 // many sleepers as events marked sleeping (invariant). This ensures that
94 // there is always a sleeper to service the remaining events.
96 // A sleeper will remove at least the event it has been waiting for
97 // unless the event has already been removed by another sleeper. Both
98 // cases preserve the invariant described above.
104 if dt := e.t - t; dt > 0 {
107 if nt, err := sleep(t, dt); err != nil {
108 // If sleep has encountered an error,
109 // there's not much we can do. We pretend
110 // that time really has advanced by the required
111 // amount and lie to the rest of the system.
128 func (eventHeap) Len() int {
132 func (eventHeap) Less(i, j int) bool {
133 return events[i].t < events[j].t
136 func (eventHeap) Swap(i, j int) {
137 events[i], events[j] = events[j], events[i]
140 func (eventHeap) Push(x interface{}) {
141 events = append(events, x.(*event))
144 func (eventHeap) Pop() interface{} {
145 // TODO: possibly shrink array.