diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-01-29 20:52:43 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-01-29 20:52:43 +0000 |
commit | d6f2922e91928b5191a5c5f1b3a6b320712b5ce3 (patch) | |
tree | 4f2fad1f4b778519bdd5941185c7e1d032af055b /libgo/go/time | |
parent | 91bfca59095b1cca9d4364996866848eaaf76c26 (diff) |
libgo: Update Go library to master revision 15489/921e53d4863c.
From-SVN: r195560
Diffstat (limited to 'libgo/go/time')
-rw-r--r-- | libgo/go/time/example_test.go | 10 | ||||
-rw-r--r-- | libgo/go/time/export_test.go | 19 | ||||
-rw-r--r-- | libgo/go/time/format.go | 5 | ||||
-rw-r--r-- | libgo/go/time/internal_test.go | 2 | ||||
-rw-r--r-- | libgo/go/time/sleep.go | 15 | ||||
-rw-r--r-- | libgo/go/time/sleep_test.go | 54 | ||||
-rw-r--r-- | libgo/go/time/time.go | 4 | ||||
-rw-r--r-- | libgo/go/time/time_test.go | 16 |
8 files changed, 115 insertions, 10 deletions
diff --git a/libgo/go/time/example_test.go b/libgo/go/time/example_test.go index ea26710d8d2..cda565ff3ee 100644 --- a/libgo/go/time/example_test.go +++ b/libgo/go/time/example_test.go @@ -57,6 +57,16 @@ func ExampleDate() { // Output: Go launched at 2009-11-10 15:00:00 -0800 PST } +func ExampleTime_Format() { + const format = "Jan 2, 2006 at 3:04pm (MST)" + t := time.Date(2009, time.November, 10, 15, 0, 0, 0, time.Local) + fmt.Println(t.Format(format)) + fmt.Println(t.UTC().Format(format)) + // Output: + // Nov 10, 2009 at 3:00pm (PST) + // Nov 10, 2009 at 11:00pm (UTC) +} + func ExampleTime_Round() { t := time.Date(0, 0, 0, 12, 15, 30, 918273645, time.UTC) round := []time.Duration{ diff --git a/libgo/go/time/export_test.go b/libgo/go/time/export_test.go new file mode 100644 index 00000000000..130ca8f7ebe --- /dev/null +++ b/libgo/go/time/export_test.go @@ -0,0 +1,19 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package time + +import ( + "sync" +) + +func ResetLocalOnceForTest() { + localOnce = sync.Once{} + localLoc = Location{} +} + +func ForceUSPacificForTesting() { + ResetLocalOnceForTest() + localOnce.Do(initTestingZone) +} diff --git a/libgo/go/time/format.go b/libgo/go/time/format.go index 417e8f8d7a8..8d21040bf9a 100644 --- a/libgo/go/time/format.go +++ b/libgo/go/time/format.go @@ -9,7 +9,7 @@ import "errors" // These are predefined layouts for use in Time.Format. // The standard time used in the layouts is: // Mon Jan 2 15:04:05 MST 2006 -// which is Unix time 1136243045. Since MST is GMT-0700, +// which is Unix time 1136239445. Since MST is GMT-0700, // the standard time can be thought of as // 01/02 03:04:05PM '06 -0700 // To define your own format, write down what the standard time would look @@ -637,7 +637,8 @@ func skip(value, prefix string) (string, error) { // // Elements omitted from the value are assumed to be zero or, when // zero is impossible, one, so parsing "3:04pm" returns the time -// corresponding to Jan 1, year 0, 15:04:00 UTC. +// corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is +// 0, this time is before the zero Time). // Years must be in the range 0000..9999. The day of the week is checked // for syntax but it is otherwise ignored. func Parse(layout, value string) (Time, error) { diff --git a/libgo/go/time/internal_test.go b/libgo/go/time/internal_test.go index b753896d775..918a9f33be6 100644 --- a/libgo/go/time/internal_test.go +++ b/libgo/go/time/internal_test.go @@ -6,7 +6,7 @@ package time func init() { // force US/Pacific for time zone tests - localOnce.Do(initTestingZone) + ForceUSPacificForTesting() } var Interrupt = interrupt diff --git a/libgo/go/time/sleep.go b/libgo/go/time/sleep.go index 657e2541031..1e6b4f2e442 100644 --- a/libgo/go/time/sleep.go +++ b/libgo/go/time/sleep.go @@ -35,10 +35,10 @@ type Timer struct { // Stop prevents the Timer from firing. // It returns true if the call stops the timer, false if the timer has already -// expired or stopped. +// expired or been stopped. // Stop does not close the channel, to prevent a read from the channel succeeding // incorrectly. -func (t *Timer) Stop() (ok bool) { +func (t *Timer) Stop() bool { return stopTimer(&t.r) } @@ -58,6 +58,17 @@ func NewTimer(d Duration) *Timer { return t } +// Reset changes the timer to expire after duration d. +// It returns true if the timer had been active, false if the timer had +// expired or been stopped. +func (t *Timer) Reset(d Duration) bool { + when := nano() + int64(d) + active := stopTimer(&t.r) + t.r.when = when + startTimer(&t.r) + return active +} + func sendTime(now int64, c interface{}) { // Non-blocking send of time on c. // Used in NewTimer, it cannot block anyway (buffer). diff --git a/libgo/go/time/sleep_test.go b/libgo/go/time/sleep_test.go index caa9702c9fc..e5a9fdf5408 100644 --- a/libgo/go/time/sleep_test.go +++ b/libgo/go/time/sleep_test.go @@ -54,9 +54,10 @@ func TestAfterStress(t *testing.T) { go func() { for atomic.LoadUint32(&stop) == 0 { runtime.GC() - // Need to yield, because otherwise - // the main goroutine will never set the stop flag. - runtime.Gosched() + // Yield so that the OS can wake up the timer thread, + // so that it can generate channel sends for the main goroutine, + // which will eventually set stop = 1 for us. + Sleep(Nanosecond) } }() c := Tick(1) @@ -246,3 +247,50 @@ func TestSleepZeroDeadlock(t *testing.T) { } <-c } + +func testReset(d Duration) error { + t0 := NewTimer(2 * d) + Sleep(d) + if t0.Reset(3*d) != true { + return errors.New("resetting unfired timer returned false") + } + Sleep(2 * d) + select { + case <-t0.C: + return errors.New("timer fired early") + default: + } + Sleep(2 * d) + select { + case <-t0.C: + default: + return errors.New("reset timer did not fire") + } + + if t0.Reset(50*Millisecond) != false { + return errors.New("resetting expired timer returned true") + } + return nil +} + +func TestReset(t *testing.T) { + // We try to run this test with increasingly larger multiples + // until one works so slow, loaded hardware isn't as flaky, + // but without slowing down fast machines unnecessarily. + const unit = 25 * Millisecond + tries := []Duration{ + 1 * unit, + 3 * unit, + 7 * unit, + 15 * unit, + } + var err error + for _, d := range tries { + err = testReset(d) + if err == nil { + t.Logf("passed using duration %v", d) + return + } + } + t.Error(err) +} diff --git a/libgo/go/time/time.go b/libgo/go/time/time.go index 190cc37ddbd..d291672af10 100644 --- a/libgo/go/time/time.go +++ b/libgo/go/time/time.go @@ -261,8 +261,8 @@ func (t Time) abs() uint64 { // extracting both return values from a single zone lookup. func (t Time) locabs() (name string, offset int, abs uint64) { l := t.loc - if l == nil { - l = &utcLoc + if l == nil || l == &localLoc { + l = l.get() } // Avoid function call if we hit the local time cache. sec := t.sec + internalToUnix diff --git a/libgo/go/time/time_test.go b/libgo/go/time/time_test.go index 0224fed4bdf..a8953aefd33 100644 --- a/libgo/go/time/time_test.go +++ b/libgo/go/time/time_test.go @@ -1227,6 +1227,22 @@ func TestParseDurationRoundTrip(t *testing.T) { } } +// golang.org/issue/4622 +func TestLocationRace(t *testing.T) { + ResetLocalOnceForTest() // reset the Once to trigger the race + + c := make(chan string, 1) + go func() { + c <- Now().String() + }() + Now().String() + <-c + Sleep(100 * Millisecond) + + // Back to Los Angeles for subsequent tests: + ForceUSPacificForTesting() +} + var ( t Time u int64 |