mirror of
https://github.com/apple/pkl.git
synced 2026-04-25 01:38:34 +02:00
Fix concurrency bug in PackageResolvers (#220)
Access to field "isClosed" must be guarded.
This commit is contained in:
@@ -36,6 +36,7 @@ import java.util.Collections;
|
|||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
@@ -71,7 +72,7 @@ class PackageResolvers {
|
|||||||
|
|
||||||
private final SecurityManager securityManager;
|
private final SecurityManager securityManager;
|
||||||
|
|
||||||
private boolean isClosed = false;
|
private final AtomicBoolean isClosed = new AtomicBoolean();
|
||||||
|
|
||||||
protected final Object lock = new Object();
|
protected final Object lock = new Object();
|
||||||
|
|
||||||
@@ -83,9 +84,7 @@ class PackageResolvers {
|
|||||||
/** Retrieves a dependency's metadata file. */
|
/** Retrieves a dependency's metadata file. */
|
||||||
public DependencyMetadata getDependencyMetadata(PackageUri uri, @Nullable Checksums checksums)
|
public DependencyMetadata getDependencyMetadata(PackageUri uri, @Nullable Checksums checksums)
|
||||||
throws IOException, SecurityManagerException {
|
throws IOException, SecurityManagerException {
|
||||||
if (isClosed) {
|
checkNotClosed();
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
var metadata = cachedDependencyMetadata.get(uri);
|
var metadata = cachedDependencyMetadata.get(uri);
|
||||||
if (metadata == null) {
|
if (metadata == null) {
|
||||||
@@ -125,29 +124,23 @@ class PackageResolvers {
|
|||||||
@Override
|
@Override
|
||||||
public List<PathElement> listElements(PackageAssetUri uri, @Nullable Checksums checksums)
|
public List<PathElement> listElements(PackageAssetUri uri, @Nullable Checksums checksums)
|
||||||
throws IOException, SecurityManagerException {
|
throws IOException, SecurityManagerException {
|
||||||
if (isClosed) {
|
checkNotClosed();
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
return doListElements(uri, checksums);
|
return doListElements(uri, checksums);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasElement(PackageAssetUri uri, @Nullable Checksums checksums)
|
public boolean hasElement(PackageAssetUri uri, @Nullable Checksums checksums)
|
||||||
throws IOException, SecurityManagerException {
|
throws IOException, SecurityManagerException {
|
||||||
if (isClosed) {
|
checkNotClosed();
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
return doHasElement(uri, checksums);
|
return doHasElement(uri, checksums);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
synchronized (lock) {
|
if (!isClosed.getAndSet(true)) {
|
||||||
if (isClosed) {
|
synchronized (lock) {
|
||||||
return;
|
cachedDependencyMetadata.clear();
|
||||||
}
|
}
|
||||||
cachedDependencyMetadata.clear();
|
|
||||||
isClosed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +229,12 @@ class PackageResolvers {
|
|||||||
packageUri.getDisplayName(),
|
packageUri.getDisplayName(),
|
||||||
dependencyMetadata.getPackageZipUrl());
|
dependencyMetadata.getPackageZipUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkNotClosed() {
|
||||||
|
if (isClosed.get()) {
|
||||||
|
throw new IllegalStateException("Package resolver has already been closed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user