context: Uniformly pass cancelCtx by pointer.

cancelCtx has an embedded sync.Mutex. This change causes an extra
allocation when creating a new timerCtx via WithDeadline, but that seems
minor when compared with better locking discipline. If it turns out to
be a problem, the whole cancelCtx struct can be flattened into timerCtx.

Addresses part of golang/go#14839.

Change-Id: Ie86ed1b63592b521aefde747d5fafcd49ac18178
Reviewed-on: https://go-review.googlesource.com/20840
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/context/context.go b/context/context.go
index 77b64d0..19235cf 100644
--- a/context/context.go
+++ b/context/context.go
@@ -210,13 +210,13 @@
 // call cancel as soon as the operations running in this Context complete.
 func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
 	c := newCancelCtx(parent)
-	propagateCancel(parent, &c)
-	return &c, func() { c.cancel(true, Canceled) }
+	propagateCancel(parent, c)
+	return c, func() { c.cancel(true, Canceled) }
 }
 
 // newCancelCtx returns an initialized cancelCtx.
-func newCancelCtx(parent Context) cancelCtx {
-	return cancelCtx{
+func newCancelCtx(parent Context) *cancelCtx {
+	return &cancelCtx{
 		Context: parent,
 		done:    make(chan struct{}),
 	}
@@ -259,7 +259,7 @@
 		case *cancelCtx:
 			return c, true
 		case *timerCtx:
-			return &c.cancelCtx, true
+			return c.cancelCtx, true
 		case *valueCtx:
 			parent = c.Context
 		default:
@@ -377,7 +377,7 @@
 // implement Done and Err.  It implements cancel by stopping its timer then
 // delegating to cancelCtx.cancel.
 type timerCtx struct {
-	cancelCtx
+	*cancelCtx
 	timer *time.Timer // Under cancelCtx.mu.
 
 	deadline time.Time