aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexa Panfil <alexapizza@google.com>2020-10-23 17:23:23 +0000
committerMatthias Sohn <matthias.sohn@sap.com>2020-11-06 19:20:08 -0400
commit4f3161d3cc1af6ff725d6e7fb21909001df62705 (patch)
treeb5de206a0bb0d67b54df78e8c260f68d130a8d46
parentd76088bca6077579f5b8fe669147a31ce7bbd6ad (diff)
downloadjgit-4f3161d3cc1af6ff725d6e7fb21909001df62705.tar.gz
jgit-4f3161d3cc1af6ff725d6e7fb21909001df62705.zip
Fix bug in PerformanceLogContext
PerformanceLogContext threw NullPointerException when multiple threads tried to add an event to the PerformanceLogContext. The cause for this is that the ThreadLocal was initialized only in the class constructor for the first thread; for subsequent threads it was null. To fix this initialize eventRecords for each thread. Change-Id: I18ef67dff8f0488e3ad28c9bbc18ce73d5168cf9 Signed-off-by: Alexa Panfil <alexapizza@google.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java45
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogContext.java6
2 files changed, 40 insertions, 11 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java
index e061833d17..f3c1ddec8a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java
@@ -1,6 +1,7 @@
package org.eclipse.jgit.logging;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
@@ -37,30 +38,58 @@ public class PerformanceLogContextTest {
}
@Test
- public void testAddEventsTwoThreads() {
- TestRunnable thread1 = new TestRunnable("record1", 1);
- TestRunnable thread2 = new TestRunnable("record2", 2);
+ public void testAddEventsTwoThreads() throws InterruptedException {
+ TestRunnable runnable1 = new TestRunnable("record1", 1);
+ TestRunnable runnable2 = new TestRunnable("record2", 2);
- new Thread(thread1).start();
- new Thread(thread2).start();
+ Thread thread1 = new Thread(runnable1);
+ Thread thread2 = new Thread(runnable2);
+
+ thread1.start();
+ thread2.start();
+
+ thread1.join();
+ thread2.join();
+ assertEquals(1, runnable1.getEventRecordsCount());
+ assertEquals(1, runnable2.getEventRecordsCount());
+ assertFalse(runnable1.isThrown());
+ assertFalse(runnable2.isThrown());
}
private static class TestRunnable implements Runnable {
private String name;
+
private long durationMs;
+ private long eventRecordsCount;
+
+ private boolean thrown = false;
+
public TestRunnable(String name, long durationMs) {
this.name = name;
this.durationMs = durationMs;
}
+ public boolean isThrown() {
+ return thrown;
+ }
+
+ public long getEventRecordsCount() {
+ return eventRecordsCount;
+ }
+
@Override
public void run() {
PerformanceLogRecord record = new PerformanceLogRecord(name,
durationMs);
- PerformanceLogContext.getInstance().addEvent(record);
- assertEquals(1, PerformanceLogContext.getInstance()
- .getEventRecords().size());
+ try {
+ PerformanceLogContext.getInstance().addEvent(record);
+ eventRecordsCount = PerformanceLogContext.getInstance()
+ .getEventRecords().size();
+ PerformanceLogContext.getInstance().cleanEvents();
+ } catch (Exception e) {
+ thrown = true;
+ }
}
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogContext.java b/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogContext.java
index 4421efd7f3..fab0dd102a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogContext.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogContext.java
@@ -24,10 +24,10 @@ public class PerformanceLogContext {
private static final PerformanceLogContext INSTANCE = new PerformanceLogContext();
/** List that stores events as performance logs. */
- private final ThreadLocal<List<PerformanceLogRecord>> eventRecords = new ThreadLocal<>();
+ private static final ThreadLocal<List<PerformanceLogRecord>> eventRecords = ThreadLocal
+ .withInitial(ArrayList::new);
private PerformanceLogContext() {
- eventRecords.set(new ArrayList<>());
}
/**
@@ -62,6 +62,6 @@ public class PerformanceLogContext {
* Removes all of the existing records from the current list of events.
*/
public void cleanEvents() {
- eventRecords.get().clear();
+ eventRecords.remove();
}
} \ No newline at end of file