src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java
changeset 58863 c16ac7a2eba4
parent 55256 3b22c7e00573
child 59226 a0f39cc47387
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java	Wed Oct 30 16:14:56 2019 +0100
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java	Wed Oct 30 19:43:52 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -31,7 +31,6 @@
 import static jdk.jfr.internal.LogTag.JFR;
 import static jdk.jfr.internal.LogTag.JFR_SYSTEM;
 
-import java.io.IOException;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.time.Duration;
@@ -59,6 +58,7 @@
 
 public final class PlatformRecorder {
 
+
     private final List<PlatformRecording> recordings = new ArrayList<>();
     private final static List<SecureRecorderListener> changeListeners = new ArrayList<>();
     private final Repository repository;
@@ -96,6 +96,7 @@
             Thread t = SecuritySupport.createThreadWitNoPermissions("Permissionless thread", ()-> {
                 result.add(new Timer("JFR Recording Scheduler", true));
             });
+            jvm.exclude(t);
             t.start();
             t.join();
             return result.get(0);
@@ -204,7 +205,7 @@
         repository.clear();
     }
 
-    synchronized void start(PlatformRecording recording) {
+    synchronized long start(PlatformRecording recording) {
         // State can only be NEW or DELAYED because of previous checks
         Instant now = Instant.now();
         recording.setStartTime(now);
@@ -215,14 +216,17 @@
         }
         boolean toDisk = recording.isToDisk();
         boolean beginPhysical = true;
+        long streamInterval = recording.getStreamIntervalMillis();
         for (PlatformRecording s : getRecordings()) {
             if (s.getState() == RecordingState.RUNNING) {
                 beginPhysical = false;
                 if (s.isToDisk()) {
                     toDisk = true;
                 }
+                streamInterval = Math.min(streamInterval, s.getStreamIntervalMillis());
             }
         }
+        long startNanos = -1;
         if (beginPhysical) {
             RepositoryChunk newChunk = null;
             if (toDisk) {
@@ -233,6 +237,7 @@
             }
             currentChunk = newChunk;
             jvm.beginRecording_();
+            startNanos = jvm.getChunkStartNanos();
             recording.setState(RecordingState.RUNNING);
             updateSettings();
             writeMetaEvents();
@@ -242,6 +247,7 @@
                 newChunk = repository.newChunk(now);
                 RequestEngine.doChunkEnd();
                 MetadataRepository.getInstance().setOutput(newChunk.getUnfishedFile().toString());
+                startNanos = jvm.getChunkStartNanos();
             }
             recording.setState(RecordingState.RUNNING);
             updateSettings();
@@ -251,8 +257,12 @@
             }
             currentChunk = newChunk;
         }
+        if (toDisk) {
+            RequestEngine.setFlushInterval(streamInterval);
+        }
+        RequestEngine.doChunkBegin();
 
-        RequestEngine.doChunkBegin();
+        return startNanos;
     }
 
     synchronized void stop(PlatformRecording recording) {
@@ -267,6 +277,7 @@
         Instant now = Instant.now();
         boolean toDisk = false;
         boolean endPhysical = true;
+        long streamInterval = Long.MAX_VALUE;
         for (PlatformRecording s : getRecordings()) {
             RecordingState rs = s.getState();
             if (s != recording && RecordingState.RUNNING == rs) {
@@ -274,6 +285,7 @@
                 if (s.isToDisk()) {
                     toDisk = true;
                 }
+                streamInterval = Math.min(streamInterval, s.getStreamIntervalMillis());
             }
         }
         OldObjectSample.emit(recording);
@@ -309,6 +321,13 @@
             currentChunk = newChunk;
             RequestEngine.doChunkBegin();
         }
+
+        if (toDisk) {
+            RequestEngine.setFlushInterval(streamInterval);
+        } else {
+            RequestEngine.setFlushInterval(Long.MAX_VALUE);
+        }
+
         recording.setState(RecordingState.STOPPED);
     }
 
@@ -338,6 +357,18 @@
         MetadataRepository.getInstance().setSettings(list);
     }
 
+    public synchronized void rotateIfRecordingToDisk() {
+        boolean disk = false;
+        for (PlatformRecording s : getRecordings()) {
+            if (RecordingState.RUNNING == s.getState() && s.isToDisk()) {
+                disk = true;
+            }
+        }
+        if (disk) {
+            rotateDisk();
+        }
+    }
+
     synchronized void rotateDisk() {
         Instant now = Instant.now();
         RepositoryChunk newChunk = repository.newChunk(now);
@@ -395,14 +426,14 @@
                 r.appendChunk(chunk);
             }
         }
+        FilePurger.purge();
     }
 
     private void writeMetaEvents() {
-
         if (activeRecordingEvent.isEnabled()) {
+            ActiveRecordingEvent event = ActiveRecordingEvent.EVENT.get();
             for (PlatformRecording r : getRecordings()) {
                 if (r.getState() == RecordingState.RUNNING && r.shouldWriteMetadataEvent()) {
-                    ActiveRecordingEvent event = new ActiveRecordingEvent();
                     event.id = r.getId();
                     event.name = r.getName();
                     WriteableUserPath p = r.getDestination();
@@ -415,6 +446,8 @@
                     event.maxSize = size == null ? Long.MAX_VALUE : size;
                     Instant start = r.getStartTime();
                     event.recordingStart = start == null ? Long.MAX_VALUE : start.toEpochMilli();
+                    Duration fi = r.getFlushInterval();
+                    event.flushInterval = fi == null ? Long.MAX_VALUE : fi.toMillis();
                     event.commit();
                 }
             }
@@ -448,7 +481,7 @@
                 JVM.FILE_DELTA_CHANGE.wait(duration < 10 ? 10 : duration);
             }
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            // Ignore
         }
     }
 
@@ -550,4 +583,7 @@
         target.setStopTime(endTime);
         target.setInternalDuration(Duration.between(startTime, endTime));
     }
+
+
+
 }