private static void performUnderGuard(@NotNull CompileContext context,
                                          @NotNull JpsMavenRepositoryLibraryDescriptor descriptor,
                                          @NotNull List<File> roots,
                                          @NotNull ThrowingRunnable action) throws Exception {
      Stream<Guard> descriptorGuard = Stream.of(getDescriptorGuard(context, descriptor));
      Stream<Guard> rootsGuards = roots.stream()
        .map(rootFile -> Path.of(FileUtil.toCanonicalPath(rootFile.getAbsolutePath())))
        // sort and filter equal guards to acquire locks always in similar order and prevent deadlocks
        .sorted()
        .distinct()
        .map(rootAbsolutePath -> getRootGuard(context, rootAbsolutePath));

      List<Guard> guards = Stream.concat(descriptorGuard, rootsGuards).collect(Collectors.toList());
      int lockedGuardsCounter = 0;
      try {
        for (Guard guard : guards) {
          if (!guard.requestProcessing(context.getCancelStatus())) {
            return;
          }
          lockedGuardsCounter++;
        }

        action.run();
      }
      finally {
        // release only guards we're holding; release in reversed order to prevent deadlocks
        for (Guard guard : ContainerUtil.reverse(guards.subList(0, lockedGuardsCounter))) {
          guard.finish();
        }
      }
    }
private static void performUnderGuard(@NotNull CompileContext context,
                                          @NotNull JpsMavenRepositoryLibraryDescriptor descriptor,
                                          @NotNull List<File> roots,
                                          @NotNull ThrowingRunnable action)