8272588: Enhanced recording parsing
Reviewed-by: mgronlun, rhalade, mschoene
This commit is contained in:
parent
4d4ba814ae
commit
f0f0ddbf6d
src/jdk.jfr/share/classes/jdk/jfr
@ -136,6 +136,8 @@ public interface EventStream extends AutoCloseable {
|
||||
* <p>
|
||||
* By default, the stream starts with the next event flushed by Flight
|
||||
* Recorder.
|
||||
* <p>
|
||||
* Only trusted disk repositories should be opened.
|
||||
*
|
||||
* @param directory location of the disk repository, not {@code null}
|
||||
*
|
||||
@ -166,6 +168,8 @@ public interface EventStream extends AutoCloseable {
|
||||
* Creates an event stream from a file.
|
||||
* <p>
|
||||
* By default, the stream starts with the first event in the file.
|
||||
* <p>
|
||||
* Only recording files from trusted sources should be opened.
|
||||
*
|
||||
* @param file location of the file, not {@code null}
|
||||
*
|
||||
|
@ -70,6 +70,8 @@ public final class RecordingFile implements Closeable {
|
||||
|
||||
/**
|
||||
* Creates a recording file.
|
||||
* <p>
|
||||
* Only recording files from trusted sources should be used.
|
||||
*
|
||||
* @param file the path of the file to open, not {@code null}
|
||||
* @throws IOException if it's not a valid recording file, or an I/O error
|
||||
@ -247,6 +249,8 @@ public final class RecordingFile implements Closeable {
|
||||
* <p>
|
||||
* This method is intended for simple cases where it's convenient to read all
|
||||
* events in a single operation. It isn't intended for reading large files.
|
||||
* <p>
|
||||
* Only recording files from trusted sources should be used.
|
||||
*
|
||||
* @param path the path to the file, not {@code null}
|
||||
*
|
||||
|
@ -113,7 +113,7 @@ public final class ChunkHeader {
|
||||
byte fs;
|
||||
input.positionPhysical(absoluteChunkStart + FILE_STATE_POSITION);
|
||||
while ((fs = input.readPhysicalByte()) == UPDATING_CHUNK_HEADER) {
|
||||
Utils.takeNap(1);
|
||||
input.pollWait();
|
||||
input.positionPhysical(absoluteChunkStart + FILE_STATE_POSITION);
|
||||
}
|
||||
return fs;
|
||||
@ -180,7 +180,7 @@ public final class ChunkHeader {
|
||||
finished = true;
|
||||
return;
|
||||
}
|
||||
Utils.takeNap(1);
|
||||
input.pollWait();
|
||||
}
|
||||
} finally {
|
||||
input.position(pos);
|
||||
|
@ -145,6 +145,7 @@ public final class EventDirectoryStream extends AbstractEventStream {
|
||||
}
|
||||
currentChunkStartNanos = repositoryFiles.getTimestamp(path);
|
||||
try (RecordingInput input = new RecordingInput(path.toFile(), fileAccess)) {
|
||||
input.setStreamed();
|
||||
currentParser = new ChunkParser(input, disp.parserConfiguration, parserState);
|
||||
long segmentStart = currentParser.getStartNanos() + currentParser.getChunkDuration();
|
||||
long filterStart = validStartTime ? disp.startNanos : segmentStart;
|
||||
|
@ -49,6 +49,7 @@ public final class EventFileStream extends AbstractEventStream {
|
||||
public EventFileStream(@SuppressWarnings("removal") AccessControlContext acc, Path file) throws IOException {
|
||||
super(acc, null, Collections.emptyList());
|
||||
this.input = new RecordingInput(file.toFile(), FileAccess.UNPRIVILEGED);
|
||||
this.input.setStreamed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -214,6 +214,7 @@ public final class OngoingStream extends EventByteStream {
|
||||
return false;
|
||||
}
|
||||
input = new RecordingInput(path.toFile(), SecuritySupport.PRIVILEGED);
|
||||
input.setStreamed();
|
||||
header = new ChunkHeader(input);
|
||||
}
|
||||
return true;
|
||||
|
@ -31,6 +31,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.file.Path;
|
||||
import jdk.jfr.internal.Utils;
|
||||
|
||||
public final class RecordingInput implements DataInput, AutoCloseable {
|
||||
|
||||
@ -66,6 +67,7 @@ public final class RecordingInput implements DataInput, AutoCloseable {
|
||||
}
|
||||
private final int blockSize;
|
||||
private final FileAccess fileAccess;
|
||||
private long pollCount = 1000;
|
||||
private RandomAccessFile file;
|
||||
private String filename;
|
||||
private Block currentBlock = new Block();
|
||||
@ -439,4 +441,18 @@ public final class RecordingInput implements DataInput, AutoCloseable {
|
||||
initialize(path.toFile());
|
||||
}
|
||||
|
||||
// Marks that it is OK to poll indefinitely for file update
|
||||
// By default, only 1000 polls are allowed
|
||||
public void setStreamed() {
|
||||
this.pollCount = Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
// Wait for file to be updated
|
||||
public void pollWait() throws IOException {
|
||||
pollCount--;
|
||||
if (pollCount < 0) {
|
||||
throw new IOException("Recording file is stuck in locked stream state.");
|
||||
}
|
||||
Utils.takeNap(1);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user