diff -r c75c241c492a -r 4ce66d271065 src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java Fri Aug 09 19:16:55 2019 +0200 +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java Tue Aug 13 03:58:29 2019 +0200 @@ -26,7 +26,6 @@ import java.io.IOException; import java.nio.file.DirectoryStream; -import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; @@ -52,8 +51,8 @@ private volatile boolean closed; private Path repository; - public RepositoryFiles(FileAccess fileAccess, SafePath repository) { - this.repository = repository == null ? null : repository.toPath(); + public RepositoryFiles(FileAccess fileAccess, Path repository) { + this.repository = repository; this.fileAccess = fileAccess; } @@ -62,66 +61,71 @@ } public Path lastPath() { - // Wait for chunks + if (waitForPaths()) { + return pathSet.lastEntry().getValue(); + } + return null; // closed + } + + public Path firstPath(long startTimeNanos) { + if (waitForPaths()) { + // Pick closest chunk before timestamp + Long time = pathSet.floorKey(startTimeNanos); + if (time != null) { + startTimeNanos = time; + } + return path(startTimeNanos); + } + return null; // closed + } + + private boolean waitForPaths() { while (!closed) { try { if (updatePaths()) { break; } } catch (IOException e) { - // ignore, not yet available + Logger.log(LogTag.JFR_SYSTEM_STREAMING, LogLevel.DEBUG, "IOException during repository file scan " + e.getMessage()); + // This can happen if a chunk is being removed + // between the file was discovered and an instance + // was accessed, or if new file has been written yet + // Just ignore, and retry later. } - } - if (closed) { - return null; + nap(); } - // Pick the last - return pathSet.lastEntry().getValue(); - } - - public Path firstPath(long startTimeNanos) { - return path(startTimeNanos, true); + return !closed; } public Path nextPath(long startTimeNanos) { - return path(startTimeNanos, false); + return path(startTimeNanos); } - private Path path(long timestamp, boolean first) { - while (!closed) { - Long time = timestamp; - if (first) { - // Pick closest chunk before timestamp - time = pathSet.floorKey(timestamp); - } - if (time != null) { - SortedMap after = pathSet.tailMap(time); - if (!after.isEmpty()) { - Path path = after.get(after.firstKey()); - Logger.log(LogTag.JFR_SYSTEM_STREAMING, LogLevel.TRACE, "Return path " + path + " for start time nanos " + timestamp); - return path; - } + private Path path(long timestamp) { + if (closed) { + return null; + } + while (true) { + SortedMap after = pathSet.tailMap(timestamp); + if (!after.isEmpty()) { + Path path = after.get(after.firstKey()); + Logger.log(LogTag.JFR_SYSTEM_STREAMING, LogLevel.TRACE, "Return path " + path + " for start time nanos " + timestamp); + return path; } - try { - if (updatePaths()) { - continue; - } - } catch (IOException e) { - Logger.log(LogTag.JFR_SYSTEM_STREAMING, LogLevel.DEBUG, "IOException during repository file scan " + e.getMessage()); - // This can happen if a chunk is being removed - // between the file was discovered and an instance - // of an EventSet was constructed. Just ignore, - // and retry later. - } - try { - synchronized (pathSet) { - pathSet.wait(1000); - } - } catch (InterruptedException e) { - // ignore + if (!waitForPaths()) { + return null; // closed } } - return null; + } + + private void nap() { + try { + synchronized (pathSet) { + pathSet.wait(1000); + } + } catch (InterruptedException e) { + // ignore + } } private boolean updatePaths() throws IOException { @@ -163,7 +167,7 @@ for (Path p : added) { // Only add files that have a complete header // as the JVM may be in progress writing the file - long size = Files.size(p); + long size = fileAccess.fileSize(p); if (size >= ChunkHeader.HEADER_SIZE) { long startNanos = readStartTime(p); pathSet.put(startNanos, p);