--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/AbstractEventStream.java Fri Aug 02 20:04:02 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/AbstractEventStream.java Fri Aug 02 20:05:23 2019 +0200
@@ -332,7 +332,6 @@
private void execute() {
JVM.getJVM().exclude(Thread.currentThread());
try {
- updateStartNanos();
process();
} catch (IOException e) {
if (!isClosed()) {
@@ -345,19 +344,6 @@
}
}
- // User setting overrides default
- private void updateStartNanos() {
- if (configuration.getStartTime() != null) {
- StreamConfiguration c = new StreamConfiguration(configuration);
- try {
- c.setStartNanos(c.getStartTime().toEpochMilli() * 1_000_000L);
- } catch (ArithmeticException ae) {
- c.setStartNanos(Long.MAX_VALUE);
- }
- updateConfiguration(c);
- }
- }
-
private void logException(Exception e) {
// FIXME: e.printStackTrace(); for debugging purposes,
// remove before before integration
@@ -522,6 +508,9 @@
throw new IllegalStateException("Event stream can only be started once");
}
StreamConfiguration c = new StreamConfiguration(configuration);
+ if (c.getStartTime() != null) {
+ startNanos= c.getStartTime().toEpochMilli() * 1_000_000L;
+ }
c.setStartNanos(startNanos);
c.setStarted(true);
updateConfiguration(c);
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventDirectoryStream.java Fri Aug 02 20:04:02 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventDirectoryStream.java Fri Aug 02 20:05:23 2019 +0200
@@ -35,6 +35,7 @@
import java.util.Objects;
import java.util.function.Consumer;
+import jdk.jfr.internal.SecuritySupport.SafePath;
import jdk.jfr.internal.consumer.RecordingInput;
import jdk.jfr.internal.consumer.RepositoryFiles;
@@ -58,7 +59,7 @@
public DirectoryStream(AccessControlContext acc, Path p) throws IOException {
super(acc);
- repositoryFiles = new RepositoryFiles(p);
+ repositoryFiles = new RepositoryFiles(new SafePath(p));
}
@Override
@@ -98,7 +99,9 @@
}
runFlushActions();
}
-
+ if (isClosed()) {
+ return;
+ }
path = repositoryFiles.nextPath(chunkStartNanos);
if (path == null) {
return; // stream closed
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java Fri Aug 02 20:04:02 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java Fri Aug 02 20:05:23 2019 +0200
@@ -44,15 +44,16 @@
import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.Logger;
import jdk.jfr.internal.Repository;
+import jdk.jfr.internal.SecuritySupport.SafePath;
public final class RepositoryFiles {
- private final Path repostory;
+ private final Path repository;
private final NavigableMap<Long, Path> pathSet = new TreeMap<>();
private final Map<Path, Long> pathLookup = new HashMap<>();
private volatile boolean closed;
- public RepositoryFiles(Path repostory) {
- this.repostory = repostory;
+ public RepositoryFiles(SafePath repository) {
+ this.repository = repository.toPath();
}
public long getTimestamp(Path p) {
@@ -71,14 +72,17 @@
return e.getValue();
}
}
- SortedMap<Long, Path> after = pathSet.tailMap(startTimeNanos);
- if (!after.isEmpty()) {
- Path path = after.get(after.firstKey());
- Logger.log(LogTag.JFR_SYSTEM_STREAMING, LogLevel.TRACE, "Return path " + path + " for start time nanos " + startTimeNanos);
- return path;
+ Long f = pathSet.floorKey(startTimeNanos);
+ if (f != null) {
+ SortedMap<Long, Path> after = pathSet.tailMap(f);
+ if (!after.isEmpty()) {
+ Path path = after.get(after.firstKey());
+ Logger.log(LogTag.JFR_SYSTEM_STREAMING, LogLevel.TRACE, "Return path " + path + " for start time nanos " + startTimeNanos);
+ return path;
+ }
}
try {
- if (updatePaths(repostory)) {
+ if (updatePaths(repository)) {
continue;
}
} catch (IOException e) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetStartTime.java Fri Aug 02 20:05:23 2019 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2019, 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.api.consumer.recordingstream;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import jdk.jfr.Event;
+import jdk.jfr.Name;
+import jdk.jfr.Recording;
+import jdk.jfr.StackTrace;
+import jdk.jfr.consumer.EventStream;
+
+/**
+ * @test
+ * @summary Tests RecordingStrream::setStartTime
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib
+ * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestSetStartTime
+ */
+public final class TestSetStartTime {
+
+ @Name("Mark")
+ @StackTrace(false)
+ public final static class Mark extends Event {
+ public boolean before;
+ }
+
+ public static void main(String... args) throws Exception {
+ try (Recording r = new Recording()) {
+ r.setFlushInterval(Duration.ofSeconds(1));
+ r.start();
+ Mark event1 = new Mark();
+ event1.before = true;
+ event1.commit();
+
+ Instant now = Instant.now();
+ System.out.println("Start time was " + now);
+ Mark event2 = new Mark();
+ event2.before = false;
+ event2.commit();
+ AtomicBoolean error = new AtomicBoolean();
+ try (EventStream d = EventStream.openRepository()) {
+ d.setStartTime(now);
+ d.onEvent(e -> {
+ System.out.println(e);
+ boolean early = e.getBoolean("before");
+ if (early) {
+ error.set(true);
+ } else {
+ // OK, as expected
+ d.close();
+ }
+ });
+ d.start();
+ if (error.get()) {
+ throw new Exception("Found unexpected event!");
+ }
+ }
+ }
+ }
+}
\ No newline at end of file