@@ -49,8 +49,8 @@ type MonitorManager struct {
49
49
50
50
mu struct {
51
51
syncutil.Mutex
52
- stop chan struct {}
53
- disks []* monitoredDisk
52
+ cancel context. CancelFunc
53
+ disks []* monitoredDisk
54
54
}
55
55
}
56
56
@@ -90,13 +90,14 @@ func (m *MonitorManager) Monitor(path string) (*Monitor, error) {
90
90
91
91
// The design maintains the invariant that the disk stat polling loop
92
92
// is always running unless there are no disks being monitored.
93
- if m .mu .stop == nil {
93
+ if m .mu .cancel == nil {
94
94
collector , err := newStatsCollector (m .fs )
95
95
if err != nil {
96
96
return nil , err
97
97
}
98
- m .mu .stop = make (chan struct {})
99
- go m .monitorDisks (collector , m .mu .stop )
98
+ ctx , cancel := context .WithCancel (context .Background ())
99
+ m .mu .cancel = cancel
100
+ go m .monitorDisks (ctx , collector )
100
101
}
101
102
}
102
103
disk .refCount ++
@@ -105,7 +106,7 @@ func (m *MonitorManager) Monitor(path string) (*Monitor, error) {
105
106
}
106
107
107
108
func (m * MonitorManager ) unrefDisk (disk * monitoredDisk ) {
108
- var stop chan struct {}
109
+ var cancel context. CancelFunc
109
110
func () {
110
111
m .mu .Lock ()
111
112
defer m .mu .Unlock ()
@@ -123,14 +124,14 @@ func (m *MonitorManager) unrefDisk(disk *monitoredDisk) {
123
124
// If the MonitorManager has no disks left to monitor, the disk stat polling loop can
124
125
// be stopped.
125
126
if len (m .mu .disks ) == 0 {
126
- stop = m .mu .stop
127
- m .mu .stop = nil
127
+ cancel = m .mu .cancel
128
+ m .mu .cancel = nil
128
129
}
129
130
}
130
131
}()
131
132
132
- if stop != nil {
133
- stop <- struct {}{}
133
+ if cancel != nil {
134
+ cancel ()
134
135
}
135
136
}
136
137
@@ -139,22 +140,15 @@ type statsCollector interface {
139
140
}
140
141
141
142
// monitorDisks runs a loop collecting disk stats for all monitored disks.
142
- //
143
- // NB: A stop channel must be passed down to ensure that the function terminates during the
144
- // race where the MonitorManager creates a new stop channel after unrefDisk sends a message
145
- // across the old stop channel.
146
- func (m * MonitorManager ) monitorDisks (collector statsCollector , stop chan struct {}) {
147
- // TODO(jackson): Should we propagate a context here to replace the stop
148
- // channel?
149
- ctx := context .TODO ()
143
+ // monitorDisks returns when the context is done.
144
+ func (m * MonitorManager ) monitorDisks (ctx context.Context , collector statsCollector ) {
150
145
ticker := time .NewTicker (DefaultDiskStatsPollingInterval )
151
146
defer ticker .Stop ()
152
147
153
148
every := log .Every (5 * time .Minute )
154
149
for {
155
150
select {
156
- case <- stop :
157
- close (stop )
151
+ case <- ctx .Done ():
158
152
return
159
153
case <- ticker .C :
160
154
m .mu .Lock ()
0 commit comments