Commit b6fdb7d8 authored by Aaron Jacobs's avatar Aaron Jacobs Committed by Sameer Ajmani

context: Be clear that users must cancel the result of WithCancel.

This is necessary for cleanup of any goroutine that blocks on
ctx.Done(), as is done in e.g. propagateCancel in context.go. It is
already specified for WithTimeout and WithDeadline, whose descriptions I
have simplified here.

Change-Id: I6b30605decb8c0b7c1296c3f8852f9ad305ad4b7
Reviewed-on: https://go-review.googlesource.com/5022Reviewed-by: 's avatarSameer Ajmani <sameer@golang.org>
parent 94722490
...@@ -205,6 +205,9 @@ type CancelFunc func() ...@@ -205,6 +205,9 @@ type CancelFunc func()
// WithCancel returns a copy of parent with a new Done channel. The returned // WithCancel returns a copy of parent with a new Done channel. The returned
// context's Done channel is closed when the returned cancel function is called // context's Done channel is closed when the returned cancel function is called
// or when the parent context's Done channel is closed, whichever happens first. // or when the parent context's Done channel is closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
c := newCancelCtx(parent) c := newCancelCtx(parent)
propagateCancel(parent, &c) propagateCancel(parent, &c)
...@@ -343,9 +346,8 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) { ...@@ -343,9 +346,8 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) {
// cancel function is called, or when the parent context's Done channel is // cancel function is called, or when the parent context's Done channel is
// closed, whichever happens first. // closed, whichever happens first.
// //
// Canceling this context releases resources associated with the deadline // Canceling this context releases resources associated with it, so code should
// timer, so code should call cancel as soon as the operations running in this // call cancel as soon as the operations running in this Context complete.
// Context complete.
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
// The current deadline is already sooner than the new one. // The current deadline is already sooner than the new one.
...@@ -405,9 +407,8 @@ func (c *timerCtx) cancel(removeFromParent bool, err error) { ...@@ -405,9 +407,8 @@ func (c *timerCtx) cancel(removeFromParent bool, err error) {
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
// //
// Canceling this context releases resources associated with the deadline // Canceling this context releases resources associated with it, so code should
// timer, so code should call cancel as soon as the operations running in this // call cancel as soon as the operations running in this Context complete:
// Context complete:
// //
// func slowOperationWithTimeout(ctx context.Context) (Result, error) { // func slowOperationWithTimeout(ctx context.Context) (Result, error) {
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) // ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment