Repository: ignite Updated Branches: refs/heads/master a9c7264ad -> e1601f2d3
IGNITE-9840 Fixed deadlock on transactional future on client node caused by pending objects dump - Fixes #5268. Signed-off-by: Alexey Goncharuk <alexey.goncha...@gmail.com> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e1601f2d Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e1601f2d Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e1601f2d Branch: refs/heads/master Commit: e1601f2d3f47438d6c0d963c0b213fa4b8585926 Parents: a9c7264 Author: Ilya Lantukh <ilant...@gridgain.com> Authored: Thu Nov 8 12:56:22 2018 +0300 Committer: Alexey Goncharuk <alexey.goncha...@gmail.com> Committed: Thu Nov 8 12:56:22 2018 +0300 ---------------------------------------------------------------------- .../internal/binary/BinaryObjectExImpl.java | 6 +++ .../binary/builder/BinaryObjectBuilderImpl.java | 3 +- .../binary/CacheObjectBinaryProcessorImpl.java | 6 ++- .../org/apache/ignite/thread/IgniteThread.java | 44 ++++++++++++-------- 4 files changed, 38 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/e1601f2d/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java index 920a296..f213ad9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java @@ -32,6 +32,7 @@ import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.thread.IgniteThread; import org.jetbrains.annotations.Nullable; /** @@ -201,12 +202,17 @@ public abstract class BinaryObjectExImpl implements BinaryObjectEx { BinaryType meta; + IgniteThread.onForbidBinaryMetadataRequestSectionEntered(); + try { meta = rawType(); } catch (BinaryObjectException ignore) { meta = null; } + finally { + IgniteThread.onForbidBinaryMetadataRequestSectionLeft(); + } if (meta == null || !S.INCLUDE_SENSITIVE) return S.toString(S.INCLUDE_SENSITIVE ? BinaryObject.class.getSimpleName() : "BinaryObject", http://git-wip-us.apache.org/repos/asf/ignite/blob/e1601f2d/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java index 6bf9999..ce3807d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java @@ -178,8 +178,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder { Thread curThread = Thread.currentThread(); if (curThread instanceof IgniteThread) - writer.failIfUnregistered(((IgniteThread)curThread).executingEntryProcessor() && - ((IgniteThread)curThread).holdsTopLock()); + writer.failIfUnregistered(((IgniteThread)curThread).isForbiddenToRequestBinaryMetadata()); writer.typeId(typeId); http://git-wip-us.apache.org/repos/asf/ignite/blob/e1601f2d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java index e825c54..346e8a7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java @@ -558,7 +558,9 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm @Nullable public BinaryMetadata metadata0(final int typeId) { BinaryMetadataHolder holder = metadataLocCache.get(typeId); - if (holder == null) { + IgniteThread curThread = IgniteThread.current(); + + if (holder == null && (curThread == null || !curThread.isForbiddenToRequestBinaryMetadata())) { if (ctx.clientNode()) { try { transport.requestUpToDateMetadata(typeId).get(); @@ -572,7 +574,7 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm } if (holder != null) { - if (IgniteThread.current() instanceof IgniteDiscoveryThread) + if (curThread instanceof IgniteDiscoveryThread) return holder.metadata(); if (holder.pendingVersion() - holder.acceptedVersion() > 0) { http://git-wip-us.apache.org/repos/asf/ignite/blob/e1601f2d/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java b/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java index 6f65e0e..e37e6a7 100644 --- a/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java +++ b/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java @@ -57,10 +57,10 @@ public class IgniteThread extends Thread { private final byte plc; /** */ - private boolean executingEntryProcessor; + private boolean holdsTopLock; /** */ - private boolean holdsTopLock; + private boolean forbiddenToRequestBinaryMetadata; /** * Creates thread with given worker. @@ -164,17 +164,10 @@ public class IgniteThread extends Thread { } /** - * @return {@code True} if thread is currently executing entry processor. - */ - public boolean executingEntryProcessor() { - return executingEntryProcessor; - } - - /** - * @return {@code True} if thread is currently holds topology lock. + * @return {@code True} if thread is not allowed to request binary metadata to avoid potential deadlock. */ - public boolean holdsTopLock() { - return holdsTopLock; + public boolean isForbiddenToRequestBinaryMetadata() { + return holdsTopLock || forbiddenToRequestBinaryMetadata; } /** @@ -183,11 +176,8 @@ public class IgniteThread extends Thread { public static void onEntryProcessorEntered(boolean holdsTopLock) { Thread curThread = Thread.currentThread(); - if (curThread instanceof IgniteThread) { - ((IgniteThread)curThread).executingEntryProcessor = true; - + if (curThread instanceof IgniteThread) ((IgniteThread)curThread).holdsTopLock = holdsTopLock; - } } /** @@ -197,7 +187,27 @@ public class IgniteThread extends Thread { Thread curThread = Thread.currentThread(); if (curThread instanceof IgniteThread) - ((IgniteThread)curThread).executingEntryProcessor = false; + ((IgniteThread)curThread).holdsTopLock = false; + } + + /** + * Callback on entering critical section where binary metadata requests are forbidden. + */ + public static void onForbidBinaryMetadataRequestSectionEntered() { + Thread curThread = Thread.currentThread(); + + if (curThread instanceof IgniteThread) + ((IgniteThread)curThread).forbiddenToRequestBinaryMetadata = true; + } + + /** + * Callback on leaving critical section where binary metadata requests are forbidden. + */ + public static void onForbidBinaryMetadataRequestSectionLeft() { + Thread curThread = Thread.currentThread(); + + if (curThread instanceof IgniteThread) + ((IgniteThread)curThread).forbiddenToRequestBinaryMetadata = false; } /**