Skip to content

Commit 1575014

Browse files
committed
EventDrivenUpdateGraph: Prevent requestRefresh from update threads (no nested refreshes allowed)
1 parent d90c674 commit 1575014

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

engine/table/src/main/java/io/deephaven/engine/updategraph/impl/EventDrivenUpdateGraph.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,20 @@ public int parallelismFactor() {
5353
*/
5454
@Override
5555
public void requestRefresh() {
56+
if (isUpdateThread.get()) {
57+
throw new IllegalStateException("Cannot request a refresh from an update thread");
58+
}
5659
maybeStart();
5760
// Do the work to refresh everything, driven by this thread. Note that we acquire the lock "early" in order to
5861
// avoid any inconsistencies w.r.t. assumptions about clock, lock, and update-thread state.
5962
final long lockStartTimeNanos = System.nanoTime();
6063
exclusiveLock().doLocked(() -> {
6164
reportLockWaitNanos(System.nanoTime() - lockStartTimeNanos);
62-
final boolean wasUpdateThread = isUpdateThread.get();
63-
if (!wasUpdateThread) {
64-
isUpdateThread.set(true);
65-
}
65+
isUpdateThread.set(true);
6666
try (final SafeCloseable ignored = ExecutionContext.newBuilder().setUpdateGraph(this).build().open()) {
6767
refreshAllTables();
6868
} finally {
69-
if (!wasUpdateThread) {
70-
isUpdateThread.remove();
71-
}
69+
isUpdateThread.remove();
7270
}
7371
});
7472
final long nowNanos = System.nanoTime();

engine/table/src/test/java/io/deephaven/engine/updategraph/impl/TestEventDrivenUpdateGraph.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import io.deephaven.engine.table.impl.perf.UpdatePerformanceTracker;
1818
import io.deephaven.engine.table.impl.sources.LongSingleValueSource;
1919
import io.deephaven.engine.testutil.TstUtils;
20+
import io.deephaven.engine.updategraph.TerminalNotification;
2021
import io.deephaven.engine.updategraph.UpdateGraph;
2122
import io.deephaven.engine.util.TableTools;
2223
import io.deephaven.util.SafeCloseable;
@@ -26,7 +27,9 @@
2627
import org.junit.*;
2728

2829
import java.nio.file.Path;
30+
import java.util.ArrayList;
2931
import java.util.Collections;
32+
import java.util.List;
3033
import java.util.concurrent.*;
3134

3235
import static io.deephaven.engine.context.TestExecutionContext.OPERATION_INITIALIZATION;
@@ -170,6 +173,7 @@ public void testSimpleModify() {
170173
@Test
171174
public void testRefreshRace() throws ExecutionException, InterruptedException, TimeoutException {
172175
final EventDrivenUpdateGraph eventDrivenUpdateGraph = EventDrivenUpdateGraph.newBuilder("TestEDUG").build();
176+
final List<Runnable> retainedReferences = new ArrayList<>();
173177

174178
final MutableInt sourceRefreshCount = new MutableInt(0);
175179
final Runnable sleepingSource = () -> {
@@ -180,6 +184,7 @@ public void testRefreshRace() throws ExecutionException, InterruptedException, T
180184
Assert.fail("Interrupted while sleeping");
181185
}
182186
};
187+
retainedReferences.add(sleepingSource);
183188
eventDrivenUpdateGraph.addSource(sleepingSource);
184189

185190
final int numConcurrentRefreshes = 10;
@@ -199,6 +204,21 @@ public void testRefreshRace() throws ExecutionException, InterruptedException, T
199204
}
200205

201206
Assert.assertEquals(numConcurrentRefreshes, sourceRefreshCount.intValue());
207+
Assert.assertEquals(sleepingSource, retainedReferences.get(0));
208+
}
209+
210+
@Test
211+
public void testIllegalRefresh() {
212+
final EventDrivenUpdateGraph eventDrivenUpdateGraph = EventDrivenUpdateGraph.newBuilder("TestEDUG").build();
213+
214+
eventDrivenUpdateGraph.addNotification(new TerminalNotification() {
215+
@Override
216+
public void run() {
217+
Assert.assertThrows(IllegalStateException.class, eventDrivenUpdateGraph::requestRefresh);
218+
}
219+
});
220+
221+
eventDrivenUpdateGraph.requestRefresh();
202222
}
203223

204224
@Test

0 commit comments

Comments
 (0)