11 // A Context is an implementation of the context.Context interface which
12 // cancels when an operating system signal (e.g. os.Interrupt) is
15 // Contexts should be created via the UntilSignal function.
17 parent context.Context
21 // The mutex synchronizes access to err and clearing the
22 // internal Signal channel after initialization.
27 // UntilSignal returns a new Context which will cancel when the parent
28 // does or when any of the specified operating system signals are
30 func UntilSignal(parent context.Context, sig ...os.Signal) *Context {
34 if err := parent.Err(); err != nil {
35 ctx.done = alreadyclosed
40 ctx.done = make(chan struct{})
41 ctx.c = make(chan os.Signal, 1)
42 signal.Notify(ctx.c, sig...)
47 func (s *Context) wait(sig ...os.Signal) {
50 case <-s.parent.Done():
68 // Cancel cancels this context, if it hasn’t already been. (If it has,
69 // this is safe but has no effect.) Canceling this context releases
70 // resources associated with it and stops listening for the configured
71 // operating system signals.
72 func (s *Context) Cancel() {
75 s.err = context.Canceled
84 // Deadline implements context.Context; a Context’s deadline is that of
86 func (s *Context) Deadline() (time.Time, bool) {
87 return s.parent.Deadline()
90 // Value implements context.Context; any Context value is that of its
92 func (s *Context) Value(key interface{}) interface{} {
93 return s.parent.Value(key)
96 // Done returns a channel that's closed when work done on behalf of this
97 // context should be canceled, either because the parent finished or
98 // because one of the configured operating system signals was received.
99 func (s *Context) Done() <-chan struct{} {
103 // Err implements context.Context; it returns context.Canceled if the
104 // context was canceled by its Cancel method; an Error if the context
105 // canceled due to a operating system signal; the parent’s error if the
106 // parent canceled before either of those; or nil if the context is not
108 func (s *Context) Err() error {
115 // Reuse the same channel for all Contexts which begin life already
117 var alreadyclosed = make(chan struct{})