package clock
import (
"context"
"fmt"
"sync"
"time"
)
func (m *Mock ) WithTimeout (parent context .Context , timeout time .Duration ) (context .Context , context .CancelFunc ) {
return m .WithDeadline (parent , m .Now ().Add (timeout ))
}
func (m *Mock ) WithDeadline (parent context .Context , deadline time .Time ) (context .Context , context .CancelFunc ) {
if cur , ok := parent .Deadline (); ok && cur .Before (deadline ) {
return context .WithCancel (parent )
}
ctx := &timerCtx {clock : m , parent : parent , deadline : deadline , done : make (chan struct {})}
propagateCancel (parent , ctx )
dur := m .Until (deadline )
if dur <= 0 {
ctx .cancel (context .DeadlineExceeded )
return ctx , func () {}
}
ctx .Lock ()
defer ctx .Unlock ()
if ctx .err == nil {
ctx .timer = m .AfterFunc (dur , func () {
ctx .cancel (context .DeadlineExceeded )
})
}
return ctx , func () { ctx .cancel (context .Canceled ) }
}
func propagateCancel(parent context .Context , child *timerCtx ) {
if parent .Done () == nil {
return
}
go func () {
select {
case <- parent .Done ():
child .cancel (parent .Err ())
case <- child .Done ():
}
}()
}
type timerCtx struct {
sync .Mutex
clock Clock
parent context .Context
deadline time .Time
done chan struct {}
err error
timer *Timer
}
func (c *timerCtx ) cancel (err error ) {
c .Lock ()
defer c .Unlock ()
if c .err != nil {
return
}
c .err = err
close (c .done )
if c .timer != nil {
c .timer .Stop ()
c .timer = nil
}
}
func (c *timerCtx ) Deadline () (deadline time .Time , ok bool ) { return c .deadline , true }
func (c *timerCtx ) Done () <-chan struct {} { return c .done }
func (c *timerCtx ) Err () error { return c .err }
func (c *timerCtx ) Value (key interface {}) interface {} { return c .parent .Value (key ) }
func (c *timerCtx ) String () string {
return fmt .Sprintf ("clock.WithDeadline(%s [%s])" , c .deadline , c .deadline .Sub (c .clock .Now ()))
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .