-
Notifications
You must be signed in to change notification settings - Fork 4
/
diff
73 lines (67 loc) · 2.22 KB
/
diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
diff --git a/signal.go b/signal.go
index 97572b1..3faf912 100644
--- a/signal.go
+++ b/signal.go
@@ -17,25 +17,20 @@ func (e ErrSignal) Error() string {
return fmt.Sprintf("got signal: %s", e.Signal)
}
-// signalNotify is the signal notify function.
-// It is used in a variable for testing purposes.
-var signalNotify = signal.Notify
-
// WithSignal returns a context which is done when an OS signal is sent.
// parent is a parent context to wrap.
-// sigWhiteList is a list of signals to listen on. According to the
-// signal.Notify behavior, an empty list will listen to any OS signal.
+// sigWhiteList is a list of signals to listen on.
+// According to the signal.Notify behavior, an empty list will listen
+// to any OS signal.
// If an OS signal closed this context, ErrSignal will be returned in
-// the Err() method.
+// the Err() method of the returned context.
// This method creates the signal channel and invokes a goroutine.
func WithSignal(parent context.Context, sigWhiteList ...os.Signal) context.Context {
- sig := make(chan os.Signal, 1)
- signalNotify(sig, sigWhiteList...)
- s := &signalCtx{
+ s := &signalContext{
Context: parent,
done: make(chan struct{}),
}
- go s.watch(sig)
+ go s.watch(sigWhiteList)
return s
}
@@ -52,21 +47,32 @@ func Interrupt() context.Context {
return WithSignal(context.Background(), os.Interrupt)
}
-type signalCtx struct {
+// signalContext implements the context interface.
+// It is being cancelled with OS signal cancellation.
+type signalContext struct {
context.Context
done chan struct{}
err error
}
-func (s *signalCtx) Done() <-chan struct{} {
+func (s *signalContext) Done() <-chan struct{} {
return s.done
}
-func (s *signalCtx) Err() error {
+func (s *signalContext) Err() error {
return s.err
}
-func (s *signalCtx) watch(sigCh <-chan os.Signal) {
+// signalNotify is the signal notify function.
+// It is used in a variable for testing purposes.
+var signalNotify = signal.Notify
+
+// watch should be run in a goroutine when creating a signalContext.
+// It
+func (s *signalContext) watch(sigWhiteList []os.Signal) {
+ sigCh := make(chan os.Signal, 1)
+ signalNotify(sigCh, sigWhiteList...)
+
select {
case <-s.Context.Done():
s.err = s.Context.Err()