11 // A Context is an implementation of the context.Context interface which
12 // completes when a signal (e.g. os.Interrupt) is received.
14 // Contexts should be created via the UntilSignal function.
16 parent context.Context
20 // The mutex synchronizes access to err and clearing the
21 // internal Signal channel after initialization.
26 // UntilSignal returns a new Context which will complete when the parent
27 // does or when any of the specified signals are received.
28 func UntilSignal(parent context.Context, sig ...os.Signal) *Context {
31 ctx.done = make(chan struct{})
33 if err := parent.Err(); err != nil {
39 ctx.c = make(chan os.Signal, 1)
40 signal.Notify(ctx.c, sig...)
45 func (s *Context) wait(sig ...os.Signal) {
48 case <-s.parent.Done():
66 // Cancel cancels this context, if it hasn’t already been completed. (If
67 // it has, this is safe but has no effect.)
68 func (s *Context) Cancel() {
71 s.err = context.Canceled
80 // Deadline implements context.Context; a Context’s deadline is that of
82 func (s *Context) Deadline() (time.Time, bool) {
83 return s.parent.Deadline()
86 // Value implements context.Context; any value is that of its parent.
87 func (s *Context) Value(key interface{}) interface{} {
88 return s.parent.Value(key)
91 // Done implements context.Context.
92 func (s *Context) Done() <-chan struct{} {
96 // Err implements context.Context; it returns context.Canceled if the
97 // context was canceled; an Error if the context completed due to a
98 // signal; the parent’s error if the parent was done before either of
99 // those; or nil if the context is not yet done.
100 func (s *Context) Err() error {