Skip to content

Commit d5b163e

Browse files
shreyaxcopybara-github
authored andcommitted
Address race condition in ParallelVisitor
A task could potentially enqueue items and stop running by the time between checking if the processing queue is empty and the check for pending tasks. PiperOrigin-RevId: 248765394
1 parent 004099d commit d5b163e

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

src/main/java/com/google/devtools/build/lib/query2/ParallelVisitor.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ private void visitAndWaitForCompletion() throws QueryException, InterruptedExcep
257257
// 1. Errors (QueryException or InterruptedException) occurred and visitations should fail
258258
// fast.
259259
// 2. There is no pending visit in the queue and no pending task running.
260-
while (!mustJobsBeStopped() && (!processingQueue.isEmpty() || getTaskCount() > 0)) {
260+
while (!mustJobsBeStopped() && moreWorkToDo()) {
261261
// To achieve maximum efficiency, queue is drained in either of the following two
262262
// conditions:
263263
//
@@ -292,6 +292,15 @@ private void visitAndWaitForCompletion() throws QueryException, InterruptedExcep
292292
awaitTerminationAndPropagateErrorsIfAny();
293293
}
294294

295+
private boolean moreWorkToDo() {
296+
// Note that we must check the task count first -- checking the processing queue first has the
297+
// following race condition:
298+
// (1) Check processing queue and observe that it is empty
299+
// (2) A remaining task adds to the processing queue and shuts down
300+
// (3) We check the task count and observe it is empty
301+
return getTaskCount() > 0 || !processingQueue.isEmpty();
302+
}
303+
295304
private void awaitTerminationAndPropagateErrorsIfAny()
296305
throws QueryException, InterruptedException {
297306
try {

0 commit comments

Comments
 (0)