diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/SwapListener.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/SwapListener.java index b2c2f2ad9ca..065546881c2 100644 --- a/engine/table/src/main/java/io/deephaven/engine/table/impl/SwapListener.java +++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/SwapListener.java @@ -157,10 +157,19 @@ protected synchronized boolean end(@SuppressWarnings("unused") final long clockC if (success) { eventualResult.setLastNotificationStep(lastNotificationStep); - referenceForSource.swapDelegate(initialDelegate, eventualListener instanceof LegacyListenerAdapter - ? (LegacyListenerAdapter) eventualListener - : new WeakSimpleReference<>(eventualListener)); - forceReferenceCountToZero(); + + // note: the source table first increments the notification step before notifying children, + // deephaven-core#4556 was caused by a swap to the eventual listener prior to the children being notified. + // Therefore, we must defer the swap until after the children have been notified. + sourceTable.getUpdateGraph().addNotification(new TerminalNotification() { + @Override + public void run() { + referenceForSource.swapDelegate(initialDelegate, eventualListener instanceof LegacyListenerAdapter + ? (LegacyListenerAdapter) eventualListener + : new WeakSimpleReference<>(eventualListener)); + SwapListener.this.forceReferenceCountToZero(); + } + }); } return success;