-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Acquire an exclusive lock on the disk cache while running a garbage c…
…ollection. PiperOrigin-RevId: 679173101 Change-Id: I3a095a420e7933c4f4073c2f8d19e3b9b13fda5c
- Loading branch information
1 parent
6096b5e
commit 041faf5
Showing
4 changed files
with
87 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
src/test/java/com/google/devtools/build/lib/remote/disk/ExternalLock.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright 2024 The Bazel Authors. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
package com.google.devtools.build.lib.remote.disk; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
import com.google.devtools.build.lib.shell.Subprocess; | ||
import com.google.devtools.build.lib.shell.SubprocessBuilder; | ||
import com.google.devtools.build.lib.util.OS; | ||
import com.google.devtools.build.lib.vfs.Path; | ||
import com.google.devtools.build.runfiles.Runfiles; | ||
import java.io.IOException; | ||
|
||
/** | ||
* Runs an external process that holds a shared or exclusive lock on a file. | ||
* | ||
* <p>This is needed for testing because the JVM does not allow overlapping locks. | ||
*/ | ||
public class ExternalLock implements AutoCloseable { | ||
private static final String HELPER_PATH = | ||
"io_bazel/src/test/java/com/google/devtools/build/lib/remote/disk/external_lock_helper" | ||
+ (OS.getCurrent() == OS.WINDOWS ? ".exe" : ""); | ||
|
||
private final Subprocess subprocess; | ||
|
||
static ExternalLock getShared(Path lockPath) throws IOException { | ||
return new ExternalLock(lockPath, true); | ||
} | ||
|
||
static ExternalLock getExclusive(Path lockPath) throws IOException { | ||
return new ExternalLock(lockPath, false); | ||
} | ||
|
||
ExternalLock(Path lockPath, boolean shared) throws IOException { | ||
String binaryPath = Runfiles.preload().withSourceRepository("").rlocation(HELPER_PATH); | ||
this.subprocess = | ||
new SubprocessBuilder() | ||
.setArgv( | ||
ImmutableList.of( | ||
binaryPath, lockPath.getPathString(), shared ? "shared" : "exclusive")) | ||
.start(); | ||
// Wait for child to report that the lock has been acquired. | ||
// We could read the entire stdout/stderr here to obtain additional debugging information, | ||
// but for some reason that hangs forever on Windows, even if we close them on the child side. | ||
if (subprocess.getInputStream().read() != '!') { | ||
throw new IOException("external helper process failed"); | ||
} | ||
} | ||
|
||
@Override | ||
public void close() throws IOException { | ||
// Wait for process to exit and release the lock. | ||
subprocess.destroyAndWait(); | ||
} | ||
} |