Skip to content

Commit

Permalink
Fix concurrency bug in PackageResolvers (apple#220)
Browse files Browse the repository at this point in the history
Access to field "isClosed" must be guarded.
  • Loading branch information
translatenix authored Feb 21, 2024
1 parent 277f1e0 commit ffc629f
Showing 1 changed file with 14 additions and 15 deletions.
29 changes: 14 additions & 15 deletions pkl-core/src/main/java/org/pkl/core/packages/PackageResolvers.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import java.util.zip.ZipInputStream;
Expand Down Expand Up @@ -71,7 +72,7 @@ abstract static class AbstractPackageResolver implements PackageResolver {

private final SecurityManager securityManager;

private boolean isClosed = false;
private final AtomicBoolean isClosed = new AtomicBoolean();

protected final Object lock = new Object();

Expand All @@ -83,9 +84,7 @@ protected AbstractPackageResolver(SecurityManager securityManager) {
/** Retrieves a dependency's metadata file. */
public DependencyMetadata getDependencyMetadata(PackageUri uri, @Nullable Checksums checksums)
throws IOException, SecurityManagerException {
if (isClosed) {
throw new IllegalStateException();
}
checkNotClosed();
synchronized (lock) {
var metadata = cachedDependencyMetadata.get(uri);
if (metadata == null) {
Expand Down Expand Up @@ -125,29 +124,23 @@ protected Pair<DependencyMetadata, Checksums> readDependencyMetadataAndComputeCh
@Override
public List<PathElement> listElements(PackageAssetUri uri, @Nullable Checksums checksums)
throws IOException, SecurityManagerException {
if (isClosed) {
throw new IllegalStateException();
}
checkNotClosed();
return doListElements(uri, checksums);
}

@Override
public boolean hasElement(PackageAssetUri uri, @Nullable Checksums checksums)
throws IOException, SecurityManagerException {
if (isClosed) {
throw new IllegalStateException();
}
checkNotClosed();
return doHasElement(uri, checksums);
}

@Override
public void close() throws IOException {
synchronized (lock) {
if (isClosed) {
return;
if (!isClosed.getAndSet(true)) {
synchronized (lock) {
cachedDependencyMetadata.clear();
}
cachedDependencyMetadata.clear();
isClosed = true;
}
}

Expand Down Expand Up @@ -236,6 +229,12 @@ protected PackageLoadError invalidPackageZipUrl(
packageUri.getDisplayName(),
dependencyMetadata.getPackageZipUrl());
}

private void checkNotClosed() {
if (isClosed.get()) {
throw new IllegalStateException("Package resolver has already been closed.");
}
}
}

/**
Expand Down

0 comments on commit ffc629f

Please sign in to comment.