Skip to content

Commit

Permalink
Address race condition in ParallelVisitor
Browse files Browse the repository at this point in the history
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
  • Loading branch information
shreyax authored and copybara-github committed May 17, 2019
1 parent 004099d commit d5b163e
Showing 1 changed file with 10 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ private void visitAndWaitForCompletion() throws QueryException, InterruptedExcep
// 1. Errors (QueryException or InterruptedException) occurred and visitations should fail
// fast.
// 2. There is no pending visit in the queue and no pending task running.
while (!mustJobsBeStopped() && (!processingQueue.isEmpty() || getTaskCount() > 0)) {
while (!mustJobsBeStopped() && moreWorkToDo()) {
// To achieve maximum efficiency, queue is drained in either of the following two
// conditions:
//
Expand Down Expand Up @@ -292,6 +292,15 @@ private void visitAndWaitForCompletion() throws QueryException, InterruptedExcep
awaitTerminationAndPropagateErrorsIfAny();
}

private boolean moreWorkToDo() {
// Note that we must check the task count first -- checking the processing queue first has the
// following race condition:
// (1) Check processing queue and observe that it is empty
// (2) A remaining task adds to the processing queue and shuts down
// (3) We check the task count and observe it is empty
return getTaskCount() > 0 || !processingQueue.isEmpty();
}

private void awaitTerminationAndPropagateErrorsIfAny()
throws QueryException, InterruptedException {
try {
Expand Down

0 comments on commit d5b163e

Please sign in to comment.