8274315: JFR: One closed state per file or stream
Reviewed-by: mgronlun
This commit is contained in:
parent
e49d4a9870
commit
dfb15c3e34
@ -41,6 +41,7 @@ import jdk.jfr.internal.Type;
|
||||
import jdk.jfr.internal.consumer.ChunkHeader;
|
||||
import jdk.jfr.internal.consumer.ChunkParser;
|
||||
import jdk.jfr.internal.consumer.FileAccess;
|
||||
import jdk.jfr.internal.consumer.ParserState;
|
||||
import jdk.jfr.internal.consumer.RecordingInput;
|
||||
|
||||
/**
|
||||
@ -61,6 +62,7 @@ import jdk.jfr.internal.consumer.RecordingInput;
|
||||
*/
|
||||
public final class RecordingFile implements Closeable {
|
||||
|
||||
private final ParserState parserState = new ParserState();
|
||||
private boolean isLastEventInChunk;
|
||||
private final File file;
|
||||
private RecordingInput input;
|
||||
@ -247,7 +249,7 @@ public final class RecordingFile implements Closeable {
|
||||
private void findNext() throws IOException {
|
||||
while (nextEvent == null) {
|
||||
if (chunkParser == null) {
|
||||
chunkParser = new ChunkParser(input);
|
||||
chunkParser = new ChunkParser(input, parserState);
|
||||
} else if (!chunkParser.isLastChunk()) {
|
||||
chunkParser = chunkParser.nextChunkParser();
|
||||
} else {
|
||||
|
@ -65,7 +65,7 @@ public abstract class AbstractEventStream implements EventStream {
|
||||
private volatile Thread thread;
|
||||
private Dispatcher dispatcher;
|
||||
|
||||
private volatile boolean closed;
|
||||
protected final ParserState parserState = new ParserState();
|
||||
|
||||
private boolean daemon = false;
|
||||
|
||||
@ -215,12 +215,12 @@ public abstract class AbstractEventStream implements EventStream {
|
||||
|
||||
protected abstract void process() throws IOException;
|
||||
|
||||
protected final void setClosed(boolean closed) {
|
||||
this.closed = closed;
|
||||
protected final void closeParser() {
|
||||
parserState.close();
|
||||
}
|
||||
|
||||
protected final boolean isClosed() {
|
||||
return closed;
|
||||
return parserState.isClosed();
|
||||
}
|
||||
|
||||
public final void startAsync(long startNanos) {
|
||||
|
@ -97,7 +97,7 @@ public final class ChunkParser {
|
||||
private final RecordingInput input;
|
||||
private final ChunkHeader chunkHeader;
|
||||
private final TimeConverter timeConverter;
|
||||
|
||||
private final ParserState parserState;
|
||||
private final LongMap<ConstantLookup> constantLookups;
|
||||
|
||||
private LongMap<Type> typeMap;
|
||||
@ -105,24 +105,24 @@ public final class ChunkParser {
|
||||
private boolean chunkFinished;
|
||||
|
||||
private ParserConfiguration configuration;
|
||||
private volatile boolean closed;
|
||||
private MetadataDescriptor previousMetadata;
|
||||
private MetadataDescriptor metadata;
|
||||
private boolean staleMetadata = true;
|
||||
|
||||
public ChunkParser(RecordingInput input) throws IOException {
|
||||
this(input, new ParserConfiguration());
|
||||
public ChunkParser(RecordingInput input, ParserState ps) throws IOException {
|
||||
this(input, new ParserConfiguration(), ps);
|
||||
}
|
||||
|
||||
ChunkParser(RecordingInput input, ParserConfiguration pc) throws IOException {
|
||||
this(new ChunkHeader(input), null, pc);
|
||||
ChunkParser(RecordingInput input, ParserConfiguration pc, ParserState ps) throws IOException {
|
||||
this(new ChunkHeader(input), null, pc, ps);
|
||||
}
|
||||
|
||||
private ChunkParser(ChunkParser previous) throws IOException {
|
||||
this(new ChunkHeader(previous.input), previous, new ParserConfiguration());
|
||||
private ChunkParser(ChunkParser previous, ParserState ps) throws IOException {
|
||||
this(new ChunkHeader(previous.input), previous, new ParserConfiguration(), ps);
|
||||
}
|
||||
|
||||
private ChunkParser(ChunkHeader header, ChunkParser previous, ParserConfiguration pc) throws IOException {
|
||||
private ChunkParser(ChunkHeader header, ChunkParser previous, ParserConfiguration pc, ParserState ps) throws IOException {
|
||||
this.parserState = ps;
|
||||
this.configuration = pc;
|
||||
this.input = header.getInput();
|
||||
this.chunkHeader = header;
|
||||
@ -155,7 +155,7 @@ public final class ChunkParser {
|
||||
}
|
||||
|
||||
public ChunkParser nextChunkParser() throws IOException {
|
||||
return new ChunkParser(chunkHeader.nextHeader(), this, configuration);
|
||||
return new ChunkParser(chunkHeader.nextHeader(), this, configuration, parserState);
|
||||
}
|
||||
|
||||
private void updateConfiguration() {
|
||||
@ -280,7 +280,7 @@ public final class ChunkParser {
|
||||
Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Waiting for more data (streaming). Read so far: " + chunkHeader.getChunkSize() + " bytes");
|
||||
}
|
||||
while (true) {
|
||||
if (closed) {
|
||||
if (parserState.isClosed()) {
|
||||
return true;
|
||||
}
|
||||
if (chunkHeader.getLastNanos() > filterEnd) {
|
||||
@ -437,7 +437,7 @@ public final class ChunkParser {
|
||||
}
|
||||
|
||||
ChunkParser newChunkParser() throws IOException {
|
||||
return new ChunkParser(this);
|
||||
return new ChunkParser(this, parserState);
|
||||
}
|
||||
|
||||
public boolean isChunkFinished() {
|
||||
@ -457,7 +457,7 @@ public final class ChunkParser {
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.closed = true;
|
||||
parserState.close();
|
||||
try {
|
||||
input.close();
|
||||
} catch(IOException e) {
|
||||
|
@ -83,7 +83,7 @@ public class EventDirectoryStream extends AbstractEventStream {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
setClosed(true);
|
||||
closeParser();
|
||||
dispatcher().runCloseActions();
|
||||
repositoryFiles.close();
|
||||
if (currentParser != null) {
|
||||
@ -148,7 +148,7 @@ public class EventDirectoryStream extends AbstractEventStream {
|
||||
}
|
||||
currentChunkStartNanos = repositoryFiles.getTimestamp(path);
|
||||
try (RecordingInput input = new RecordingInput(path.toFile(), fileAccess)) {
|
||||
currentParser = new ChunkParser(input, disp.parserConfiguration);
|
||||
currentParser = new ChunkParser(input, disp.parserConfiguration, parserState);
|
||||
long segmentStart = currentParser.getStartNanos() + currentParser.getChunkDuration();
|
||||
long filterStart = validStartTime ? disp.startNanos : segmentStart;
|
||||
long filterEnd = disp.endTime != null ? disp.endNanos : Long.MAX_VALUE;
|
||||
|
@ -64,7 +64,7 @@ public final class EventFileStream extends AbstractEventStream {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
setClosed(true);
|
||||
closeParser();
|
||||
dispatcher().runCloseActions();
|
||||
try {
|
||||
input.close();
|
||||
@ -85,7 +85,7 @@ public final class EventFileStream extends AbstractEventStream {
|
||||
end = disp.endNanos;
|
||||
}
|
||||
|
||||
currentParser = new ChunkParser(input, disp.parserConfiguration);
|
||||
currentParser = new ChunkParser(input, disp.parserConfiguration, parserState);
|
||||
while (!isClosed()) {
|
||||
onMetadata(currentParser);
|
||||
if (currentParser.getStartNanos() > end) {
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.jfr.internal.consumer;
|
||||
|
||||
public final class ParserState {
|
||||
private volatile boolean closed;
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
closed = true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user