diff options
author | Andrew Gerrand <adg@golang.org> | 2010-10-11 13:45:26 +1100 |
---|---|---|
committer | Andrew Gerrand <adg@golang.org> | 2010-10-11 13:45:26 +1100 |
commit | dcb054a7fc5190b6cd482422ca98fe7a14f78f72 (patch) | |
tree | 16a6a3fb983a1553d6a4dd98310c85032ecd8449 | |
parent | 08a09ccd123e6fe5e2ec401391df1053bab47932 (diff) | |
download | go-dcb054a7fc5190b6cd482422ca98fe7a14f78f72.tar.gz |
time: add After
Permits one to easily put a timeout in a select:
select {
case <-ch:
// foo
case <-time.After(1e6):
// bar
}
R=r, rog, rsc, sameer1, PeterGo, iant, nigeltao_gnome
CC=golang-dev
http://codereview.appspot.com/2321043
Committer: Andrew Gerrand <adg@golang.org>
-rw-r--r-- | src/pkg/time/sleep.go | 30 | ||||
-rw-r--r-- | src/pkg/time/sleep_test.go | 12 |
2 files changed, 37 insertions, 5 deletions
diff --git a/src/pkg/time/sleep.go b/src/pkg/time/sleep.go index 5de5374ce..702ced130 100644 --- a/src/pkg/time/sleep.go +++ b/src/pkg/time/sleep.go @@ -9,18 +9,38 @@ import ( "syscall" ) -// Sleep pauses the current goroutine for at least ns nanoseconds. Higher resolution -// sleeping may be provided by syscall.Nanosleep on some operating systems. +// Sleep pauses the current goroutine for at least ns nanoseconds. +// Higher resolution sleeping may be provided by syscall.Nanosleep +// on some operating systems. func Sleep(ns int64) os.Error { - // TODO(cw): use monotonic-time once it's available + _, err := sleep(Nanoseconds(), ns) + return err +} + +// After waits at least ns nanoseconds before sending the current time +// on the returned channel. +func After(ns int64) <-chan int64 { t := Nanoseconds() + ch := make(chan int64, 1) + go func() { + t, _ = sleep(t, ns) + ch <- t + }() + return ch +} + +// sleep takes the current time and a duration, +// pauses for at least ns nanoseconds, and +// returns the current time and an error. +func sleep(t, ns int64) (int64, os.Error) { + // TODO(cw): use monotonic-time once it's available end := t + ns for t < end { errno := syscall.Sleep(end - t) if errno != 0 && errno != syscall.EINTR { - return os.NewSyscallError("sleep", errno) + return 0, os.NewSyscallError("sleep", errno) } t = Nanoseconds() } - return nil + return t, nil } diff --git a/src/pkg/time/sleep_test.go b/src/pkg/time/sleep_test.go index 7ec6c4943..4934a3869 100644 --- a/src/pkg/time/sleep_test.go +++ b/src/pkg/time/sleep_test.go @@ -24,3 +24,15 @@ func TestSleep(t *testing.T) { t.Fatalf("Sleep(%d) slept for only %d ns", delay, duration) } } + +func TestAfter(t *testing.T) { + const delay = int64(100e6) + start := Nanoseconds() + end := <-After(delay) + if duration := Nanoseconds() - start; duration < delay { + t.Fatalf("After(%d) slept for only %d ns", delay, duration) + } + if min := start + delay; end < min { + t.Fatalf("After(%d) expect >= %d, got %d", delay, min, end) + } +} |