Does anybody knows how does context underlying works in Go?
I see that by calling WithCancel, new CancelCtx will be called
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
if parent == nil {
panic("cannot create context from nil parent")
}
c := newCancelCtx(parent)
propagateCancel(parent, &c)
return &c, func() { c.cancel(true, Canceled) }
}
// newCancelCtx returns an initialized cancelCtx.
func newCancelCtx(parent Context) cancelCtx {
return cancelCtx{Context: parent}
}
And in the newCancelCtx, cancelCtx construct is initialized and returned.
In the cancelCtx, the done property is just an instance from type of atomic.Value.

But at the stage of calling the cancel, done properly is turned into the chan struct{}

So my question is how is done property in cancelCtx converted from atomic.Value to chan struct{}?
ctx.doneholds achan struct{}in theatomic.Value.In the code you included a picture of, you can see how the context code extracts the channel:
c.done.Load()retrieves the value (if any) stored in theatomic.Value(which hasanytype), and then type-asserts it tochan struct{}.