github.com/qiniu/go-sdk/v7@v7.27.0/internal/context/go1.19.go (about) 1 //go:build !1.20 2 // +build !1.20 3 4 package context 5 6 import ( 7 "context" 8 "sync" 9 ) 10 11 type ( 12 Context = context.Context 13 CancelCauseFunc func(cause error) 14 cancelCauseErrorKey struct{} 15 cancelCauseErrorValue struct { 16 mutex sync.Mutex 17 err error 18 } 19 ) 20 21 func Cause(c Context) error { 22 if v := c.Value(cancelCauseErrorKey{}); v != nil { 23 if val, ok := v.(*cancelCauseErrorValue); ok { 24 val.mutex.Lock() 25 defer val.mutex.Unlock() 26 return val.err 27 } 28 } 29 return c.Err() 30 } 31 32 func WithCancelCause(parent Context) (ctx Context, cancel CancelCauseFunc) { 33 errWrapper := new(cancelCauseErrorValue) 34 newCtx, cancelFunc := context.WithCancel(context.WithValue(parent, cancelCauseErrorKey{}, errWrapper)) 35 return newCtx, func(cause error) { 36 errWrapper.mutex.Lock() 37 defer errWrapper.mutex.Unlock() 38 if errWrapper.err == nil { 39 errWrapper.err = cause 40 } 41 cancelFunc() 42 } 43 } 44 45 func Background() Context { 46 return context.Background() 47 }