|  | 
|  | 1 | +// Copyright 2022 The Bazel Authors. All rights reserved. | 
|  | 2 | +// | 
|  | 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 4 | +// you may not use this file except in compliance with the License. | 
|  | 5 | +// You may obtain a copy of the License at | 
|  | 6 | +// | 
|  | 7 | +//    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | +// | 
|  | 9 | +// Unless required by applicable law or agreed to in writing, software | 
|  | 10 | +// distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 | +// See the License for the specific language governing permissions and | 
|  | 13 | +// limitations under the License. | 
|  | 14 | +package com.google.devtools.build.lib.runtime; | 
|  | 15 | + | 
|  | 16 | +import static com.google.common.base.Preconditions.checkNotNull; | 
|  | 17 | +import static com.google.common.base.Preconditions.checkState; | 
|  | 18 | +import static java.util.concurrent.TimeUnit.SECONDS; | 
|  | 19 | + | 
|  | 20 | +import com.google.common.util.concurrent.ThreadFactoryBuilder; | 
|  | 21 | +import com.google.devtools.build.lib.util.AbruptExitException; | 
|  | 22 | +import java.util.concurrent.ExecutorService; | 
|  | 23 | +import java.util.concurrent.Executors; | 
|  | 24 | +import javax.annotation.Nullable; | 
|  | 25 | + | 
|  | 26 | +/** A {@link BlazeModule} that waits for submitted tasks to terminate after every command. */ | 
|  | 27 | +public class BlockWaitingModule extends BlazeModule { | 
|  | 28 | +  @Nullable private ExecutorService executorService; | 
|  | 29 | + | 
|  | 30 | +  @Override | 
|  | 31 | +  public void beforeCommand(CommandEnvironment env) throws AbruptExitException { | 
|  | 32 | +    checkState(executorService == null, "executorService must be null"); | 
|  | 33 | + | 
|  | 34 | +    executorService = | 
|  | 35 | +        Executors.newCachedThreadPool( | 
|  | 36 | +            new ThreadFactoryBuilder().setNameFormat("block-waiting-%d").build()); | 
|  | 37 | +  } | 
|  | 38 | + | 
|  | 39 | +  @SuppressWarnings("FutureReturnValueIgnored") | 
|  | 40 | +  public void submit(Runnable task) { | 
|  | 41 | +    checkNotNull(executorService, "executorService must not be null"); | 
|  | 42 | + | 
|  | 43 | +    executorService.submit(task); | 
|  | 44 | +  } | 
|  | 45 | + | 
|  | 46 | +  @Override | 
|  | 47 | +  public void afterCommand() throws AbruptExitException { | 
|  | 48 | +    checkNotNull(executorService, "executorService must not be null"); | 
|  | 49 | + | 
|  | 50 | +    executorService.shutdown(); | 
|  | 51 | +    try { | 
|  | 52 | +      executorService.awaitTermination(Long.MAX_VALUE, SECONDS); | 
|  | 53 | +    } catch (InterruptedException e) { | 
|  | 54 | +      Thread.currentThread().interrupt(); | 
|  | 55 | +    } | 
|  | 56 | + | 
|  | 57 | +    executorService = null; | 
|  | 58 | +  } | 
|  | 59 | +} | 
0 commit comments