Fixed potential deadlock due to DhtColocatedLockFuture#map being called inside topology read lock - Fixes
@@ -155,9 +155,6 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
/** */
private volatile int done;
- /** Trackable flag (here may be non-volatile). */
- private boolean trackable;
-
/** TTL for create operation. */
private final long createTtl;
@@ -266,12 +263,12 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
/** {@inheritDoc} */
@Override public boolean trackable() {
- return trackable;
+ return true;
}
/** {@inheritDoc} */
@Override public void markNotTrackable() {
- trackable = false;
+ throw new UnsupportedOperationException();
}
/**
@@ -807,6 +804,8 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
this.topVer = topVer;
}
+ cctx.mvcc().addFuture(this);
+
map(keys, false, true);
markInitialized();
@@ -829,6 +828,10 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
// We must acquire topology snapshot from the topology version future.
cctx.topology().readLock();
+ final GridDhtTopologyFuture fut;
+
+ final boolean finish;
+
try {
if (cctx.topology().stopping()) {
onDone(
@@ -839,9 +842,11 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
return;
}
- GridDhtTopologyFuture fut = cctx.topologyVersionFuture();
+ fut = cctx.topologyVersionFuture();
+
+ finish = fut.isDone();
- if (fut.isDone()) {
+ if (finish) {
Throwable err = fut.validateCache(cctx, recovery, read, null, keys);
if (err != null) {
@@ -870,6 +875,15 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
}
}
+ if (!remap)
+ cctx.mvcc().addFuture(this);
+ }
+ }
+ finally {
+ cctx.topology().readUnlock();
+ }
+
+ if (finish) {
map(keys, remap, false);
if (c != null)
@@ -891,10 +905,6 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
});
}
}
- finally {
- cctx.topology().readUnlock();
- }
- }
/**
* Maps keys to nodes. Note that we can not simply group keys by nodes and send lock request as
@@ -1139,15 +1149,6 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
iter.remove();
}
}
-
- if (hasRmtNodes) {
- trackable = true;
-
- if (!remap && !cctx.mvcc().addFuture(this))
- throw new IllegalStateException("Duplicate future ID: " + this);
- }
- else
- trackable = false;
}
finally {
/** Notify ready {@link mappings} waiters. See {@link #cancel()} */
@@ -1388,8 +1389,6 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
return true;
}
- trackable = false;
-
if (tx != null) {
if (explicit)
tx.markExplicit(cctx.localNodeId());
