You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by en...@apache.org on 2015/09/25 20:04:58 UTC

hbase git commit: HBASE-14474 DeadLock in RpcClientImpl.Connection.close()

Repository: hbase
Updated Branches:
  refs/heads/master bdea8b891 -> 32f49fa7f


HBASE-14474 DeadLock in RpcClientImpl.Connection.close()


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/32f49fa7
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/32f49fa7
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/32f49fa7

Branch: refs/heads/master
Commit: 32f49fa7fc2bcad0004e249887cc1973becc98db
Parents: bdea8b8
Author: Enis Soztutar <en...@apache.org>
Authored: Fri Sep 25 11:04:53 2015 -0700
Committer: Enis Soztutar <en...@apache.org>
Committed: Fri Sep 25 11:04:53 2015 -0700

----------------------------------------------------------------------
 .../apache/hadoop/hbase/ipc/RpcClientImpl.java  | 25 +++++++++++++-------
 1 file changed, 17 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/32f49fa7/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java
index b09674c..cb18952 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClientImpl.java
@@ -914,14 +914,20 @@ public class RpcClientImpl extends AbstractRpcClient {
           IPCUtil.write(this.out, header, call.param, cellBlock);
         } catch (IOException e) {
           // We set the value inside the synchronized block, this way the next in line
-          //  won't even try to write
-          markClosed(e);
-          close();
+          //  won't even try to write. Otherwise we might miss a call in the calls map?
+          shouldCloseConnection.set(true);
           writeException = e;
           interrupt();
         }
       }
 
+      // call close outside of the synchronized (outLock) to prevent deadlock - HBASE-14474
+      if (writeException != null) {
+        if (markClosed(writeException)) {
+          close();
+        }
+      }
+
       // We added a call, and may be started the connection close. In both cases, we
       //  need to notify the reader.
       synchronized (this) {
@@ -1022,10 +1028,11 @@ public class RpcClientImpl extends AbstractRpcClient {
           e.getStackTrace(), doNotRetry);
     }
 
-    protected synchronized void markClosed(IOException e) {
+    protected synchronized boolean markClosed(IOException e) {
       if (e == null) throw new NullPointerException();
 
-      if (shouldCloseConnection.compareAndSet(false, true)) {
+      boolean ret = shouldCloseConnection.compareAndSet(false, true);
+      if (ret) {
         if (LOG.isTraceEnabled()) {
           LOG.trace(getName() + ": marking at should close, reason: " + e.getMessage());
         }
@@ -1034,6 +1041,7 @@ public class RpcClientImpl extends AbstractRpcClient {
         }
         notifyAll();
       }
+      return ret;
     }
 
 
@@ -1142,14 +1150,15 @@ public class RpcClientImpl extends AbstractRpcClient {
     }
     if (connsToClose != null) {
       for (Connection conn : connsToClose) {
-        conn.markClosed(new InterruptedIOException("RpcClient is closing"));
-        conn.close();
+        if (conn.markClosed(new InterruptedIOException("RpcClient is closing"))) {
+          conn.close();
+        }
       }
     }
     // wait until all connections are closed
     while (!connections.isEmpty()) {
       try {
-        Thread.sleep(100);
+        Thread.sleep(10);
       } catch (InterruptedException e) {
         LOG.info("Interrupted while stopping the client. We still have " + connections.size() +
             " connections.");