aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/context/context.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/context/context.go')
-rw-r--r--libgo/go/context/context.go50
1 files changed, 41 insertions, 9 deletions
diff --git a/libgo/go/context/context.go b/libgo/go/context/context.go
index 21a40d5..05d01d0 100644
--- a/libgo/go/context/context.go
+++ b/libgo/go/context/context.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Package context defines the Context type, which carries deadlines,
-// cancelation signals, and other request-scoped values across API boundaries
+// cancellation signals, and other request-scoped values across API boundaries
// and between processes.
//
// Incoming requests to a server should create a Context, and outgoing
@@ -49,13 +49,13 @@ package context
import (
"errors"
- "fmt"
- "reflect"
+ "internal/oserror"
+ "internal/reflectlite"
"sync"
"time"
)
-// A Context carries a deadline, a cancelation signal, and other values across
+// A Context carries a deadline, a cancellation signal, and other values across
// API boundaries.
//
// Context's methods may be called by multiple goroutines simultaneously.
@@ -93,7 +93,7 @@ type Context interface {
// }
//
// See https://blog.golang.org/pipelines for more examples of how to use
- // a Done channel for cancelation.
+ // a Done channel for cancellation.
Done() <-chan struct{}
// If Done is not yet closed, Err returns nil.
@@ -163,6 +163,9 @@ type deadlineExceededError struct{}
func (deadlineExceededError) Error() string { return "context deadline exceeded" }
func (deadlineExceededError) Timeout() bool { return true }
func (deadlineExceededError) Temporary() bool { return true }
+func (deadlineExceededError) Is(target error) bool {
+ return target == oserror.ErrTimeout || target == oserror.ErrTemporary
+}
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
@@ -217,6 +220,7 @@ func TODO() Context {
// A CancelFunc tells an operation to abandon its work.
// A CancelFunc does not wait for the work to stop.
+// A CancelFunc may be called by multiple goroutines simultaneously.
// After the first call, subsequent calls to a CancelFunc do nothing.
type CancelFunc func()
@@ -338,8 +342,19 @@ func (c *cancelCtx) Err() error {
return err
}
+type stringer interface {
+ String() string
+}
+
+func contextName(c Context) string {
+ if s, ok := c.(stringer); ok {
+ return s.String()
+ }
+ return reflectlite.TypeOf(c).String()
+}
+
func (c *cancelCtx) String() string {
- return fmt.Sprintf("%v.WithCancel", c.Context)
+ return contextName(c.Context) + ".WithCancel"
}
// cancel closes c.done, cancels each of c's children, and, if
@@ -420,7 +435,9 @@ func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
}
func (c *timerCtx) String() string {
- return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, time.Until(c.deadline))
+ return contextName(c.cancelCtx.Context) + ".WithDeadline(" +
+ c.deadline.String() + " [" +
+ time.Until(c.deadline).String() + "])"
}
func (c *timerCtx) cancel(removeFromParent bool, err error) {
@@ -468,7 +485,7 @@ func WithValue(parent Context, key, val interface{}) Context {
if key == nil {
panic("nil key")
}
- if !reflect.TypeOf(key).Comparable() {
+ if !reflectlite.TypeOf(key).Comparable() {
panic("key is not comparable")
}
return &valueCtx{parent, key, val}
@@ -481,8 +498,23 @@ type valueCtx struct {
key, val interface{}
}
+// stringify tries a bit to stringify v, without using fmt, since we don't
+// want context depending on the unicode tables. This is only used by
+// *valueCtx.String().
+func stringify(v interface{}) string {
+ switch s := v.(type) {
+ case stringer:
+ return s.String()
+ case string:
+ return s
+ }
+ return "<not Stringer>"
+}
+
func (c *valueCtx) String() string {
- return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
+ return contextName(c.Context) + ".WithValue(type " +
+ reflectlite.TypeOf(c.key).String() +
+ ", val " + stringify(c.val) + ")"
}
func (c *valueCtx) Value(key interface{}) interface{} {