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;
     }
 
     /**

Reply via email to