@@ -137,30 +137,38 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p
137
137
cmd , r := start ()
138
138
timeToStart := time .Since (startTime )
139
139
140
+ done := make (chan struct {})
141
+
140
142
go utils .Safe (func () {
141
- <- opts .Stop
142
- // we use the time it took to start the program as a way of checking if things
143
- // are running slow at the moment. This is admittedly a crude estimate, but
144
- // the point is that we only want to throttle when things are running slow
145
- // and the user is flicking through a bunch of items.
146
- self .throttle = time .Since (startTime ) < THROTTLE_TIME && timeToStart > COMMAND_START_THRESHOLD
147
- if err := oscommands .Kill (cmd ); err != nil {
148
- if ! strings .Contains (err .Error (), "process already finished" ) {
149
- self .Log .Errorf ("error when running cmd task: %v" , err )
143
+ select {
144
+ case <- done :
145
+ // The command finished and did not have to be preemptively stopped before the next command.
146
+ // No need to throttle.
147
+ self .throttle = false
148
+ case <- opts .Stop :
149
+ // we use the time it took to start the program as a way of checking if things
150
+ // are running slow at the moment. This is admittedly a crude estimate, but
151
+ // the point is that we only want to throttle when things are running slow
152
+ // and the user is flicking through a bunch of items.
153
+ self .throttle = time .Since (startTime ) < THROTTLE_TIME && timeToStart > COMMAND_START_THRESHOLD
154
+
155
+ // Kill the still-running command.
156
+ if err := oscommands .Kill (cmd ); err != nil {
157
+ if ! strings .Contains (err .Error (), "process already finished" ) {
158
+ self .Log .Errorf ("error when trying to kill cmd task: %v; Command: %v %v" , err , cmd .Path , cmd .Args )
159
+ }
150
160
}
151
- }
152
161
153
- // for pty's we need to call onDone here so that cmd.Wait() doesn't block forever
154
- onDone ()
162
+ // for pty's we need to call onDone here so that cmd.Wait() doesn't block forever
163
+ onDone ()
164
+ }
155
165
})
156
166
157
167
loadingMutex := deadlock.Mutex {}
158
168
159
169
// not sure if it's the right move to redefine this or not
160
170
self .readLines = make (chan LinesToRead , 1024 )
161
171
162
- done := make (chan struct {})
163
-
164
172
scanner := bufio .NewScanner (r )
165
173
scanner .Split (utils .ScanLinesAndTruncateWhenLongerThanBuffer (bufio .MaxScanTokenSize ))
166
174
@@ -269,8 +277,10 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p
269
277
refreshViewIfStale ()
270
278
271
279
if err := cmd .Wait (); err != nil {
272
- // it's fine if we've killed this program ourselves
273
- if ! strings .Contains (err .Error (), "signal: killed" ) {
280
+ select {
281
+ case <- opts .Stop :
282
+ // it's fine if we've killed this program ourselves
283
+ default :
274
284
self .Log .Errorf ("Unexpected error when running cmd task: %v; Failed command: %v %v" , err , cmd .Path , cmd .Args )
275
285
}
276
286
}
0 commit comments