Skip to content

Commit 8147027

Browse files
committed
Worker threads interruption cleanup
- only use InterruptibleIterator to check for thread interruption while iterating
1 parent 5d750c4 commit 8147027

File tree

8 files changed

+87
-37
lines changed

8 files changed

+87
-37
lines changed

visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaFieldsPlugin.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;
6666
import org.graalvm.visualvm.heapviewer.ui.UIThresholds;
6767
import org.graalvm.visualvm.heapviewer.utils.ExcludingIterator;
68+
import org.graalvm.visualvm.heapviewer.utils.InterruptibleIterator;
6869
import org.graalvm.visualvm.heapviewer.utils.NodesComputer;
6970
import org.graalvm.visualvm.heapviewer.utils.ProgressIterator;
7071
import org.graalvm.visualvm.heapviewer.utils.counters.InstanceCounter;
@@ -563,7 +564,7 @@ public boolean isLeaf() {
563564
};
564565
}
565566
protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {
566-
Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(instancesIterator()) {
567+
Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(new InterruptibleIterator(instancesIterator())) {
567568
@Override
568569
protected boolean exclude(Instance instance) {
569570
FieldValue value = getValueOfField(instance, fieldName);
@@ -670,7 +671,7 @@ public boolean isLeaf() {
670671
}
671672
protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {
672673
final Instance _instance = getInstance();
673-
Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(instancesIterator()) {
674+
Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(new InterruptibleIterator(instancesIterator())) {
674675
@Override
675676
protected boolean exclude(Instance instance) {
676677
FieldValue value = getValueOfField(instance, fieldName);

visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaReferencesPlugin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;
6565
import org.graalvm.visualvm.heapviewer.ui.UIThresholds;
6666
import org.graalvm.visualvm.heapviewer.utils.ExcludingIterator;
67+
import org.graalvm.visualvm.heapviewer.utils.InterruptibleIterator;
6768
import org.graalvm.visualvm.heapviewer.utils.NodesComputer;
6869
import org.graalvm.visualvm.heapviewer.utils.ProgressIterator;
6970
import org.graalvm.visualvm.lib.jfluid.heap.JavaClass;
@@ -380,7 +381,7 @@ protected HeapViewerNode createNode(Instance object) {
380381
}
381382
protected ProgressIterator<Instance> objectsIterator(int index, Progress _progress) {
382383
final Instance _instance = getInstance();
383-
Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(instancesIterator()) {
384+
Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(new InterruptibleIterator(instancesIterator())) {
384385
@Override
385386
protected boolean exclude(Instance instance) {
386387
List<Value> references = instance.getReferences();

visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/HeapViewerNode.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,14 @@ protected HeapViewerNode[] computeChildren(final RootNode root) {
160160

161161
SwingWorker<HeapViewerNode[], HeapViewerNode[]> worker = new SwingWorker<HeapViewerNode[], HeapViewerNode[]>() {
162162
protected HeapViewerNode[] doInBackground() throws Exception {
163-
// long t = System.currentTimeMillis();
163+
long t = System.currentTimeMillis();
164164
synchronized (HeapViewerNode.this) {
165165
if (currentWorker != null) {
166166
currentWorker.interrupt();
167167
// System.err.println(">>> Cancelling children of " + currentWorker);
168168
}
169169
currentWorker = Thread.currentThread();
170170
// System.err.println(">>> Computing children in " + Thread.currentThread() + "...");
171-
// Thread.dumpStack();
172171
}
173172

174173
HeapViewerNode[] ret;

visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/ExcludingIterator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ public T next() {
5858
}
5959

6060
private void computeNext() {
61-
Thread worker = Thread.currentThread();
62-
while (!worker.isInterrupted() && iterator.hasNext()) {
61+
while (iterator.hasNext()) {
6362
next = iterator.next();
6463
if (!exclude(next)) return;
6564
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.visualvm.heapviewer.utils;
26+
27+
import java.util.Iterator;
28+
29+
/**
30+
*
31+
* @author Jiri Sedlacek
32+
*/
33+
public final class InterruptibleIterator<T> implements Iterator<T> {
34+
35+
private final Iterator<T> iterator;
36+
37+
38+
public InterruptibleIterator(Iterator<T> iterator) {
39+
this.iterator = iterator;
40+
}
41+
42+
43+
@Override
44+
public boolean hasNext() {
45+
return !Thread.currentThread().isInterrupted() && iterator.hasNext();
46+
}
47+
48+
@Override
49+
public T next() {
50+
return iterator.next();
51+
}
52+
53+
}

visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/MoreObjectsNode.java

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ private T[] getObjects(int containerIndex, Heap heap, HeapViewerNodeFilter viewF
215215
try {
216216
Iterator<T> objectsIt = objectsIterator(0, progress);
217217
while (objectsIt.hasNext()) buffer.add(objectsIt.next());
218+
218219
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
219220

220221
objects = buffer.getObjects();
@@ -249,13 +250,12 @@ private HeapViewerNode[] loadChildren(int containerIndex, Progress progress) thr
249250
progress.setupKnownSteps(end);
250251

251252
try {
252-
Thread worker = Thread.currentThread();
253-
Iterator<T> objectsIt = objectsIterator(start, progress);
253+
int i = 0;
254254
nodes = new HeapViewerNode[end - start + 1];
255-
for (int i = 0; i < nodes.length; i++) {
256-
if (objectsIt.hasNext()) nodes[i] = createNode(objectsIt.next());
257-
if (worker.isInterrupted()) throw new InterruptedException();
258-
}
255+
Iterator<T> objectsIt = objectsIterator(start, progress);
256+
while (i < nodes.length && objectsIt.hasNext()) nodes[i++] = createNode(objectsIt.next());
257+
258+
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
259259
} finally {
260260
progress.finish();
261261
}
@@ -305,22 +305,21 @@ private HeapViewerNode[] computeSampleChildren(int count, Heap heap, String view
305305
progress.setupKnownSteps(iteratorObjectsCount);
306306

307307
try {
308+
int i = 0;
308309
nodes = new HeapViewerNode[count];
309310
Iterator<T> objectsIt = objectsIterator(0, progress);
311+
while (i < objectsCount && objectsIt.hasNext()) {
312+
T object = objectsIt.next();
310313

311-
Thread worker = Thread.currentThread();
312-
313-
for (int i = 0; i < objectsCount; i++) {
314-
if (objectsIt.hasNext()) {
315-
T object = objectsIt.next();
316-
317-
if (i == nextHit) {
318-
nodes[index++] = createNode(object);
319-
nextHit = index == count - 1 ? objectsCount - 1 : nextHit + step;
320-
}
314+
if (i == nextHit) {
315+
nodes[index++] = createNode(object);
316+
nextHit = index == count - 1 ? objectsCount - 1 : nextHit + step;
321317
}
322-
if (worker.isInterrupted()) throw new InterruptedException();
318+
319+
i++;
323320
}
321+
322+
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
324323
} finally {
325324
progress.finish();
326325
}

visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/NodesComputer.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx
8989
public HeapViewerNode[] computeNodes(HeapViewerNode parent, final Heap heap, String viewID, final HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {
9090
if (itemsCount <= (maxItemsCount + EXTRA_ALLOWED_ITEMS)) {
9191
// All objects unsorted
92-
HeapViewerNode[] nodes = new HeapViewerNode[itemsCount];
9392
int i = 0;
93+
HeapViewerNode[] nodes = new HeapViewerNode[itemsCount];
9494
Iterator<HeapViewerNode> nodesIt = nodesIterator(0, viewFilter, heap, progress);
9595
// Do not count progress, expected to perform fast
9696
while (nodesIt.hasNext()) nodes[i++] = nodesIt.next();
@@ -108,15 +108,13 @@ public HeapViewerNode[] computeNodes(HeapViewerNode parent, final Heap heap, Str
108108

109109
if (itemsCount < Integer.MAX_VALUE && viewFilter == null && (dataType == null || sortOrder == null || SortOrder.UNSORTED.equals(sortOrder))) {
110110
// First N objects unsorted
111-
NodesIterator nodesIt = nodesIterator(0, viewFilter, heap, progress);
111+
int i = 0;
112112
HeapViewerNode[] nodes = new HeapViewerNode[maxItemsCount + 1];
113-
Thread worker = Thread.currentThread();
113+
NodesIterator nodesIt = nodesIterator(0, viewFilter, heap, progress);
114114
// Do not count progress, expected to perform fast
115-
for (int i = 0; i < maxItemsCount; i++) {
116-
if (nodesIt.hasNext()) nodes[i] = nodesIt.next();
117-
118-
if (worker.isInterrupted()) throw new InterruptedException();
119-
}
115+
while (i < maxItemsCount && nodesIt.hasNext()) nodes[i++] = nodesIt.next();
116+
117+
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
120118

121119
Format format = Formatters.numberFormat();
122120
String moreNodesString = getMoreNodesString(format.format(itemsCount - maxItemsCount));
@@ -248,7 +246,7 @@ private class PlainObjectsIterator extends ObjectsIterator {
248246
private final Iterator<T> iterator;
249247

250248
PlainObjectsIterator(int index, Progress progress) {
251-
this.iterator = objectsIterator(index, progress);
249+
this.iterator = new InterruptibleIterator(objectsIterator(index, progress));
252250
totalItems = index;
253251
firstOwnItem = index;
254252
}
@@ -276,7 +274,7 @@ private class FilteredObjectsIterator extends ObjectsIterator {
276274
private T nextObject;
277275

278276
FilteredObjectsIterator(int index, int knownFirstOwnItem, int knownTotalOwnItems, HeapViewerNodeFilter viewFilter, Heap heap, Progress progress) {
279-
this.iterator = objectsIterator(knownFirstOwnItem, progress);
277+
this.iterator = new InterruptibleIterator(objectsIterator(knownFirstOwnItem, progress));
280278
this.knownTotalOwnItems = knownTotalOwnItems;
281279

282280
this.viewFilter = viewFilter;
@@ -327,7 +325,7 @@ private class PlainNodesIterator extends NodesIterator {
327325
private final Iterator<T> iterator;
328326

329327
PlainNodesIterator(int index, Progress progress) {
330-
this.iterator = objectsIterator(index, progress);
328+
this.iterator = new InterruptibleIterator(objectsIterator(index, progress));
331329
}
332330

333331
public boolean hasNext() {
@@ -351,7 +349,7 @@ private class FilteredNodesIterator extends NodesIterator {
351349
private HeapViewerNode nextNode;
352350

353351
FilteredNodesIterator(int index, HeapViewerNodeFilter viewFilter, Heap heap, Progress progress) {
354-
this.iterator = objectsIterator(0, progress);
352+
this.iterator = new InterruptibleIterator(objectsIterator(0, progress));
355353

356354
this.viewFilter = viewFilter;
357355
this.heap = heap;

visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/ProgressIterator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public ProgressIterator(Iterator<T> iterator, int index, boolean needsForward, P
5454

5555

5656
public boolean hasNext() {
57-
return !Thread.currentThread().isInterrupted() && iterator.hasNext();
57+
return iterator.hasNext();
5858
}
5959

6060
public T next() {

0 commit comments

Comments
 (0)