}
}
+// WithoutCancel returns a copy of parent that is not canceled when parent is canceled.
+// The returned context returns no Deadline or Err, and its Done channel is nil.
+// Calling Cause on the returned context returns nil.
+func WithoutCancel(parent Context) Context {
+ if parent == nil {
+ panic("cannot create context from nil parent")
+ }
+ return withoutCancelCtx{parent}
+}
+
+type withoutCancelCtx struct {
+ c Context
+}
+
+func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {
+ return
+}
+
+func (withoutCancelCtx) Done() <-chan struct{} {
+ return nil
+}
+
+func (withoutCancelCtx) Err() error {
+ return nil
+}
+
+func (c withoutCancelCtx) Value(key any) any {
+ return value(c, key)
+}
+
+func (c withoutCancelCtx) String() string {
+ return contextName(c.c) + ".WithoutCancel"
+}
+
// WithDeadline returns a copy of the parent context with the deadline adjusted
// to be no later than d. If the parent's deadline is already earlier than d,
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
return c
}
c = ctx.Context
+ case withoutCancelCtx:
+ if key == &cancelCtxKey {
+ // This implements Cause(ctx) == nil
+ // when ctx is created using WithoutCancel.
+ return nil
+ }
+ c = ctx.c
case *timerCtx:
if key == &cancelCtxKey {
return &ctx.cancelCtx
err: Canceled,
cause: finishedEarly,
},
+ {
+ name: "WithoutCancel",
+ ctx: func() Context {
+ return WithoutCancel(Background())
+ }(),
+ err: nil,
+ cause: nil,
+ },
+ {
+ name: "WithoutCancel canceled",
+ ctx: func() Context {
+ ctx, cancel := WithCancelCause(Background())
+ ctx = WithoutCancel(ctx)
+ cancel(finishedEarly)
+ return ctx
+ }(),
+ err: nil,
+ cause: nil,
+ },
+ {
+ name: "WithoutCancel timeout",
+ ctx: func() Context {
+ ctx, cancel := WithTimeoutCause(Background(), 0, tooSlow)
+ ctx = WithoutCancel(ctx)
+ cancel()
+ return ctx
+ }(),
+ err: nil,
+ cause: nil,
+ },
} {
if got, want := test.ctx.Err(), test.err; want != got {
t.Errorf("%s: ctx.Err() = %v want %v", test.name, got, want)
runtime.Gosched()
}
}
+
+func XTestWithoutCancel(t testingT) {
+ key, value := "key", "value"
+ ctx := WithValue(Background(), key, value)
+ ctx = WithoutCancel(ctx)
+ if d, ok := ctx.Deadline(); !d.IsZero() || ok != false {
+ t.Errorf("ctx.Deadline() = %v, %v want zero, false", d, ok)
+ }
+ if done := ctx.Done(); done != nil {
+ t.Errorf("ctx.Deadline() = %v want nil", done)
+ }
+ if err := ctx.Err(); err != nil {
+ t.Errorf("ctx.Err() = %v want nil", err)
+ }
+ if v := ctx.Value(key); v != value {
+ t.Errorf("ctx.Value(%q) = %q want %q", key, v, value)
+ }
+}