summaryrefslogtreecommitdiff
path: root/libgo/go/time
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-01-29 20:52:43 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-01-29 20:52:43 +0000
commitd6f2922e91928b5191a5c5f1b3a6b320712b5ce3 (patch)
tree4f2fad1f4b778519bdd5941185c7e1d032af055b /libgo/go/time
parent91bfca59095b1cca9d4364996866848eaaf76c26 (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.go10
-rw-r--r--libgo/go/time/export_test.go19
-rw-r--r--libgo/go/time/format.go5
-rw-r--r--libgo/go/time/internal_test.go2
-rw-r--r--libgo/go/time/sleep.go15
-rw-r--r--libgo/go/time/sleep_test.go54
-rw-r--r--libgo/go/time/time.go4
-rw-r--r--libgo/go/time/time_test.go16
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