IGNITE-1282 - Fixed deadlock caused by listener notification from the synchronized block.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/70746cbd Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/70746cbd Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/70746cbd Branch: refs/heads/ignite-1.5-tx-futs-opts Commit: 70746cbd17b4c7b4e3e218d288d82b8f4546b568 Parents: a28649e Author: Alexey Goncharuk <[email protected]> Authored: Fri Nov 20 19:11:35 2015 +0300 Committer: Alexey Goncharuk <[email protected]> Committed: Fri Nov 20 19:11:35 2015 +0300 ---------------------------------------------------------------------- .../processors/cache/GridCacheMvccManager.java | 29 ++++++++++++-------- .../cache/transactions/IgniteTxEntry.java | 3 ++ 2 files changed, 21 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/70746cbd/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java index 9104acb..2449df1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java @@ -141,18 +141,25 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter { Collection<GridCacheMvccFuture<?>> futCol = mvccFuts.get(owner.version()); if (futCol != null) { + ArrayList<GridCacheMvccFuture<?>> futColCp; + synchronized (futCol) { - for (GridCacheMvccFuture<?> fut : futCol) { - if (!fut.isDone()) { - GridCacheMvccFuture<Boolean> mvccFut = (GridCacheMvccFuture<Boolean>)fut; - - // Since this method is called outside of entry synchronization, - // we can safely invoke any method on the future. - // Also note that we don't remove future here if it is done. - // The removal is initiated from within future itself. - if (mvccFut.onOwnerChanged(entry, owner)) - return; - } + futColCp = new ArrayList<>(futCol.size()); + + futColCp.addAll(futCol); + } + + // Must invoke onOwnerChanged outside of synchronization block. + for (GridCacheMvccFuture<?> fut : futColCp) { + if (!fut.isDone()) { + GridCacheMvccFuture<Boolean> mvccFut = (GridCacheMvccFuture<Boolean>)fut; + + // Since this method is called outside of entry synchronization, + // we can safely invoke any method on the future. + // Also note that we don't remove future here if it is done. + // The removal is initiated from within future itself. + if (mvccFut.onOwnerChanged(entry, owner)) + return; } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/70746cbd/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java index 7436375..fba1513 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java @@ -839,6 +839,9 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message { if (this.ctx == null) { GridCacheContext<?, ?> cacheCtx = ctx.cacheContext(cacheId); + assert cacheCtx != null : "Failed to find cache context [cacheId=" + cacheId + + ", readyTopVer=" + ctx.exchange().readyAffinityVersion() + ']'; + if (cacheCtx.isNear() && !near) cacheCtx = cacheCtx.near().dht().context(); else if (!cacheCtx.isNear() && near)
