From f3dda985088d2fc050881b8716cb77c8e09fe2da Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 12 Jul 2017 15:00:57 +0300 Subject: [PATCH] javac ast indices: fix deadlock when index is closing due to exception --- .../CompilerReferenceServiceImpl.java | 123 ++++++++++-------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceImpl.java b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceImpl.java index c9c0899d28ed..948442a9b343 100644 --- a/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/backwardRefs/CompilerReferenceServiceImpl.java @@ -223,26 +223,27 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp @SignatureData.IteratorKind byte iteratorKind) { try { myReadDataLock.lock(); - if (myReader == null) throw new ReferenceIndexUnavailableException(); try { + if (myReader == null) throw new ReferenceIndexUnavailableException(); final int type = myReader.getNameEnumerator().tryEnumerate(rawReturnType); if (type == 0) return Collections.emptySortedSet(); return Stream.of(new SignatureData(type, iteratorKind, true), new SignatureData(type, iteratorKind, false)) .flatMap(sd -> myReader.getMembersFor(sd) - .stream() - .filter(r -> r instanceof LightRef.JavaLightMethodRef) - .map(r -> (LightRef.JavaLightMethodRef) r) - .flatMap(r -> { - LightRef.NamedLightRef[] hierarchy = myReader.getHierarchy(r.getOwner(), false, false, ChainSearchMagicConstants.MAX_HIERARCHY_SIZE); - return hierarchy == null ? Stream.empty() : Arrays.stream(hierarchy).map(c -> r.override(c.getName())); - }) - .distinct() - .map(r -> { - int count = myReader.getOccurrenceCount(r); - return count <= 1 ? null : new SignatureAndOccurrences( - new MethodIncompleteSignature((LightRef.JavaLightMethodRef)r, sd, this), - count); - })) + .stream() + .filter(r -> r instanceof LightRef.JavaLightMethodRef) + .map(r -> (LightRef.JavaLightMethodRef)r) + .flatMap(r -> { + LightRef.NamedLightRef[] hierarchy = + myReader.getHierarchy(r.getOwner(), false, false, ChainSearchMagicConstants.MAX_HIERARCHY_SIZE); + return hierarchy == null ? Stream.empty() : Arrays.stream(hierarchy).map(c -> r.override(c.getName())); + }) + .distinct() + .map(r -> { + int count = myReader.getOccurrenceCount(r); + return count <= 1 ? null : new SignatureAndOccurrences( + new MethodIncompleteSignature((LightRef.JavaLightMethodRef)r, sd, this), + count); + })) .filter(Objects::nonNull) .collect(Collectors.groupingBy(x -> x.getSignature(), Collectors.summarizingInt(x -> x.getOccurrenceCount()))) .entrySet() @@ -250,12 +251,13 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp .map(e -> new SignatureAndOccurrences(e.getKey(), (int)e.getValue().getSum())) .collect(Collectors.toCollection(TreeSet::new)); } - catch (Exception e) { - onException(e, "find methods"); - return Collections.emptySortedSet(); + finally { + myReadDataLock.unlock(); } - } finally { - myReadDataLock.unlock(); + } + catch (Exception e) { + onException(e, "find methods"); + return Collections.emptySortedSet(); } } @@ -268,8 +270,8 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp public boolean mayHappen(@NotNull LightRef qualifier, @NotNull LightRef base, int probabilityThreshold) { try { myReadDataLock.lock(); - if (myReader == null) throw new ReferenceIndexUnavailableException(); try { + if (myReader == null) throw new ReferenceIndexUnavailableException(); final TIntHashSet ids1 = myReader.getAllContainingFileIds(qualifier); final TIntHashSet ids2 = myReader.getAllContainingFileIds(base); final TIntHashSet intersection = intersection(ids1, ids2); @@ -279,76 +281,89 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceServiceEx imp } return false; } - catch (Exception e) { - onException(e, "conditional probability"); - return false; + finally { + myReadDataLock.unlock(); } - } finally { - myReadDataLock.unlock(); + } + catch (Exception e) { + onException(e, "conditional probability"); + return false; } } @NotNull @Override public String getName(int idx) throws ReferenceIndexUnavailableException { - myReadDataLock.lock(); try { - if (myReader == null) throw new ReferenceIndexUnavailableException(); - return myReader.getNameEnumerator().getName(idx); + myReadDataLock.lock(); + try { + if (myReader == null) throw new ReferenceIndexUnavailableException(); + return myReader.getNameEnumerator().getName(idx); + } + finally { + myReadDataLock.unlock(); + } } catch (Exception e) { - onException(e, "find methods"); - throw new ReferenceIndexUnavailableException(); - } finally { - myReadDataLock.unlock(); + onException(e, "find methods"); + throw new ReferenceIndexUnavailableException(); } } @Override public int getNameId(@NotNull String name) throws ReferenceIndexUnavailableException { - myReadDataLock.lock(); try { - if (myReader == null) throw new ReferenceIndexUnavailableException(); - int id; + myReadDataLock.lock(); try { + if (myReader == null) throw new ReferenceIndexUnavailableException(); + int id; id = myReader.getNameEnumerator().tryEnumerate(name); + + return id; } - catch (Exception e) { - onException(e, "get name-id"); - throw new ReferenceIndexUnavailableException(); + finally { + myReadDataLock.unlock(); } - return id; - } finally { - myReadDataLock.unlock(); + } + catch (Exception e) { + onException(e, "get name-id"); + throw new ReferenceIndexUnavailableException(); } } @NotNull @Override public LightRef.LightClassHierarchyElementDef[] getDirectInheritors(@NotNull LightRef.LightClassHierarchyElementDef baseClass) throws ReferenceIndexUnavailableException { - myReadDataLock.lock(); try { - if (myReader == null) throw new ReferenceIndexUnavailableException(); - return myReader.getDirectInheritors(baseClass); + myReadDataLock.lock(); + try { + if (myReader == null) throw new ReferenceIndexUnavailableException(); + return myReader.getDirectInheritors(baseClass); + } + finally { + myReadDataLock.unlock(); + } } catch (Exception e) { onException(e, "find methods"); throw new ReferenceIndexUnavailableException(); - } finally { - myReadDataLock.unlock(); } } @Override public int getInheritorCount(@NotNull LightRef.LightClassHierarchyElementDef baseClass) throws ReferenceIndexUnavailableException { - myReadDataLock.lock(); try { - if (myReader == null) throw new ReferenceIndexUnavailableException(); - LightRef.NamedLightRef[] hierarchy = myReader.getHierarchy(baseClass, false, true, -1); - return hierarchy == null ? -1 : hierarchy.length; - } catch (Exception e) { + myReadDataLock.lock(); + try { + if (myReader == null) throw new ReferenceIndexUnavailableException(); + LightRef.NamedLightRef[] hierarchy = myReader.getHierarchy(baseClass, false, true, -1); + return hierarchy == null ? -1 : hierarchy.length; + } + finally { + myReadDataLock.unlock(); + } + } + catch (Exception e) { onException(e, "inheritor count"); throw new ReferenceIndexUnavailableException(); - } finally { - myReadDataLock.unlock(); } }